Convert YYYYMM to MMMYY

54

5

Basing on this SO question.

Challenge is rather simple: given a date period in the format YYYYMM output it in the format MMMYY.

Rules:

  • The input will be a number or a string exactly 6 characters long, consisting only of digits.
  • Last two digits will be between 01 and 12.
  • Output must be in the form MMMYY, where MMM represents uppercase three-letter code for the month (below) and YY represents two last digits of the YYYY part of the input.

List of months with corresponding code:

MM    MMM
01    JAN
02    FEB
03    MAR
04    APR
05    MAY
06    JUN
07    JUL
08    AUG
09    SEP
10    OCT
11    NOV
12    DEC

Examples:

Input     Output
201604    APR16
200001    JAN00
000112    DEC01
123405    MAY34

pajonk

Posted 2016-06-22T19:58:22.717

Reputation: 2 480

5This question is very well-balanced. Both manual parsing and date libraries end up being about the same, at least in Python. – jqblz – 2016-06-22T20:32:44.537

10Yesterday, I saw "Convert YYYYMM to MMMYY" on HNQ beside the SO logo. Now I see the same title beside the PCG logo. I was very confused :) – cat – 2016-06-23T14:30:24.287

Answers

20

MATL, 18 14 13 bytes

4e!Z{Zc12XOXk

Input is provided as a string (enclosed in single quotes).

This version only runs in MATL on MATLAB since MATLAB is able to automatically parse datestr('2016 04').

Explanation

        % Implicitly grab input as a string
4e!     % Reshape input to be 2 x 4 (puts the year in row 1 and month in row 2)
Z{      % Place each row in a separate cell
Zc      % Join them together using a space to create 'yyyy mm' format
12      % Number literal, pre-defined datestring of 'mmmyy'
XO      % Convert from serial date number to string using this format
Xk      % Convert to uppercase
        % Implicitly display

Here is an 18 byte version which works on Octave (and therefore the online interpreter)

'yyyymm'2$YO12XOXk

Try it Online

Modified version for all test cases

Explanation

            % Implicitly grab input as a string
'yyyymm'    % Push the format string as a string literal
2$YO        % Convert to a serial date number
12          % Number literal, pre-defined datestring of 'mmmyy'
XO          % Convert from serial date number to string using this format
Xk          % Convert to uppercase
            % Implicitly display

Suever

Posted 2016-06-22T19:58:22.717

Reputation: 10 257

3I don't see how this can be beaten so.. gg – Adnan – 2016-06-22T21:01:45.037

21

Python 3, 70 bytes

from time import*
lambda s:strftime("%b%y",strptime(s,"%Y%m")).upper()

This uses the built-in strftime and strptime functions.

For 1 byte more, here's a version which parses the string manually:

lambda s:" JFMAMJJASONDAEAPAUUUECOENBRRYNLGPTVC"[int(s[4:])::12]+s[2:4]

This encodes the month names in an interesting way (thanks to Henry Gomersall for saving a byte).

jqblz

Posted 2016-06-22T19:58:22.717

Reputation: 2 062

11That manual parsing is crazy. – Morgan Thrapp – 2016-06-22T20:59:00.373

@MorganThrapp I got the idea from this answer.

– jqblz – 2016-06-22T21:09:11.960

Ugh I was going to do exactly your 72 byte answer +1 – Daniel – 2016-06-23T00:01:00.390

1Your manual version can be done in 69 bytes in Python 2 if you take a number as input: lambda n:"JFMAMJJASONDAEAPAUUUECOENBRRYNLGPTVC"[n%100-1::12]+`n`[2:4]. – xnor – 2016-06-23T08:39:19.650

@xnor Would that work for the 000112 example? – Neil – 2016-06-23T09:08:30.537

@Neil Oh, it wouldn't work there. – xnor – 2016-06-23T09:37:38.273

1Though this loses a byte: lambda s:" JFMAMJJASONDAEAPAUUUECOENBRRYNLGPTVC"[int(s[4:])::12]+s[2:4] – Henry Gomersall – 2016-06-23T10:03:28.630

Why not simply import time? – grooveplex – 2016-06-23T13:32:52.797

1@a25bedc5-3d09-41b8-82fb-ea6c353d75ae - "import time" would save you 6 characters, but would cost you 10 ("time.", twice) – TLW – 2016-06-24T03:10:50.157

18

PowerShell, 49 46 40 bytes

date "$args".insert(4,'-')-U %b%y|% *per

Try it online!

Thanks to @Joey for saving 3 bytes!

Takes input $args as an explicit string (e.g., '201604') via command-line input. Uses the string.Insert() function to put a - in the appropriate space, and that resultant string forms input to the Get-Date cmdlet with the -Uformat parameter specifying the three-month shorthand plus two-digit year. We then tack on a .ToUpper() to make the output string capitalized. That string is left on the pipeline and printing is implicit.

Also, as pointed out, this is locale-sensitive. Here's the locale information that I'm using where this works correctly.

PS C:\Tools\Scripts\golfing> get-culture

LCID             Name             DisplayName
----             ----             -----------
1033             en-US            English (United States)

AdmBorkBork

Posted 2016-06-22T19:58:22.717

Reputation: 41 581

You don't need to quote the MMMyy, since it's a simple argument to a cmdlet. You also could just use -UFormat %b%y, i.e. -u %b%y instead, which is even shorter. Side note: This solution is locale-sensitive (which I personally dislike), but would be a fair bit longer to account for that, admittedly. – Joey – 2016-06-24T15:00:38.230

Excellent call with the -UFormat instead. Thanks! I also did not know about the quotes around MMMyy - that's good to know for the future. – AdmBorkBork – 2016-06-24T15:19:15.943

18

Bash + coreutils, 18

Requires 64-bit version of date for the given testcases, which recognises dates earlier than 14th December 1901.

date -d$101 +%^b%y

Digital Trauma

Posted 2016-06-22T19:58:22.717

Reputation: 64 644

8

Retina, 71 70 bytes

Thanks to Sp3000 for saving 1 byte.

Byte count assumes ISO 8859-1 encoding. The trailing linefeed is significant.

(..)(..)$
DECNOVOCTSEPAUGJULJUNMAYAPRMARFEBJANXXX$2$*¶$1
+`...¶

R-6`.

Try it online!

Explanation

Taking 201604 as an example:

(..)(..)$
DECNOVOCTSEPAUGJULJUNMAYAPRMARFEBJANXXX$2$*¶$1

This swaps the last two digits of the year with the month while also expanding the month in unary using linefeeds, and prepending the list of months in reverse so we'd get:

20DECNOVOCTSEPAUGJULJUNMAYAPRMARFEBJANXXX¶¶¶¶16

Where the represent linefeeds (0x0A).

+`...¶

Now we repeatedly remove three non-linefeed characters followed by a linefeed. That is we eat up the list of months from the end for each linefeed representing a month:

20DECNOVOCTSEPAUGJULJUNMAYAPRMARFEBJANXXX¶¶¶¶16
20DECNOVOCTSEPAUGJULJUNMAYAPRMARFEBJAN¶¶¶16
20DECNOVOCTSEPAUGJULJUNMAYAPRMARFEB¶¶16
20DECNOVOCTSEPAUGJULJUNMAYAPRMAR¶16
20DECNOVOCTSEPAUGJULJUNMAYAPR16

This is why we've inserted that XXX: since the months start counting from 1, we'll always remove at least three characters, even for January.

R-6`.

Finally, we remove everything up to the 6th character from the end. In other words we only keep the last five characters.

Martin Ender

Posted 2016-06-22T19:58:22.717

Reputation: 184 808

That's pretty dang clever. – AdmBorkBork – 2016-06-24T12:35:30.437

7

CJam, 50 46 bytes

q2/1>~i("4H~0ë~³!ò²×¶7Ö"256b25b'Af+3/=\

Try it online. Thanks to Martin Ender for compressing the string to save a few bytes.

Explanation

q2/  e# Get input and divide it into groups of 2, like ["20" "16" "04"]
1>~  e# Discard the first item and dump the remaining array to the stack
i(   e# Convert the top value (month) to an integer and decrement it, because
     e# arrays are zero-indexed
"..."256b25b e# Convert this string from base-256 to base-25
'Af+ e# "Add" a capital A to each number to get the letters
3/   e# Divide into groups of 3 to make an array of month names
=\   e# Get the requested month and swap the elements to put the year on
     e# top, so it is printed last

NinjaBearMonkey

Posted 2016-06-22T19:58:22.717

Reputation: 9 925

6

Bash, 39 28 bytes

date -d$101 +%b%y|tr a-z A-Z

Thanks Digital Trauma!

Marco

Posted 2016-06-22T19:58:22.717

Reputation: 581

6

Java 7, 137 characters (161 bytes)

String d(String i){return Integer.toString("憯䷳烣㘿烪摿摽㛨近筍矯䏔".charAt(Integer.parseInt(i.substring(4))-1),36).toUpperCase()+i.substring(2,4);}

Consider each month name (JAN, FEB etc...) is a number in base 36 and encode it into corresponding Unicode symbol. Then get corresponding symbol from the string encode it back again in base 36 and after that some plain string manipulations.

Slightly ungolfed:

String d(String input){
return 
  Integer.toString("憯䷳烣㘿烪摿摽㛨近筍矯䏔" // encoded month names
  .charAt(Integer.parseInt(input.substring(4))-1),36) // get a symbol from encoded names at position input[4:], decode it to base 36 value
  .toUpperCase()+input.substring(2,4); // get it to upper case and add year
}

You can see it running here: https://ideone.com/IKlnPY

cliffroot

Posted 2016-06-22T19:58:22.717

Reputation: 1 080

5

05AB1E, 51 42 41 bytes

2ô¦`ï<•r–ºþ¯Bê€õaPù£—^5AºüLwÇ–è•35B3ôsèsJ

Explanation

                                           # implicit input, 123405
2ô                                         # split input into pieces of 2, ['12','34','05']
  ¦`                                       # push last 2 elements to stack, '05', '34'
    ï<                                     # convert month to its int index, 4
      •r–ºþ¯Bê€õaPù£—^5AºüLwÇ–è•35B        # get compressed string containing 3-letter months, 
                                             JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC
                                   3ô      # split into pieces of 3
                                             ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC']
                                     sè    # get month at index retrieved earlier, MAY
                                       sJ  # join with 2-digit year and implicitly print, MAY34

Try it online

9 bytes saved thanks to string compression, courtesy of @Adnan

Emigna

Posted 2016-06-22T19:58:22.717

Reputation: 50 798

1•r–ºþ¯Bê€õaPù£—^5AºüLwÇ–è•35B instead of "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC" saves 9 bytes. – Adnan – 2016-06-22T20:23:06.990

5

JavaScript, 87 84 80 79 bytes

x=>(new Date(x.replace(/.{4}/,'$&-'))+'').slice(4,7).toUpperCase()+x.slice(2,4)

To get the month, gets the date (which is formed of "YYYYMM" converted to "YYYY-MM") and retrieves the characters 5 to 8, that are exactly the first three letters of the month. But it costs much to convert it to upper case.

Demo:

function s(x) {
  return (new Date(x.replace(/.{4}/, '$&-')) + '').slice(4,7)
         .toUpperCase() + x.slice(2, 4)
}

console.log(s('201604'));
console.log(s('200001'));
console.log(s('000112'));
console.log(s('123405'));

nicael

Posted 2016-06-22T19:58:22.717

Reputation: 4 585

First should be APR16 – Downgoat – 2016-06-22T20:34:46.353

@Upgoat And what's appearing for you? – nicael – 2016-06-22T20:35:14.180

1I'm getting MAR16 – Downgoat – 2016-06-22T20:40:25.417

@Upgoat Huh, that's weird, why could it be this way? Because I get this.

– nicael – 2016-06-22T20:41:55.403

For me it does show APR16, but the third test case shows only DEC for me. – Adnan – 2016-06-22T20:42:28.467

That's really strange, could you share the whole Date object you get? So as I could see what's happening. – nicael – 2016-06-22T20:44:39.087

OK in FF, Bad in Edge and Chrome for me. – Emigna – 2016-06-22T20:46:33.893

Check the recent edit. @Enigna, what do you get? – nicael – 2016-06-22T20:47:10.947

Now they're all OK. – Emigna – 2016-06-22T20:47:22.507

@Adnan Check the edit, please - should be fine now. Can't figure that oddness with March though. – nicael – 2016-06-22T20:48:09.527

Yes, it works now :). – Adnan – 2016-06-22T20:54:09.387

@Upgoat What browser were you using? – nicael – 2016-06-22T20:56:16.963

@Emigna Does it work in all the browsers you've mentioned? (sorry for misspelling you the first time!) – nicael – 2016-06-22T20:58:23.697

Yes, it works in the 3 browsers I mentioned. – Emigna – 2016-06-22T21:09:24.603

Could you, um, replace x.replace(/.{4}/,'$&-') with x.replace(/..$/,'-$&')? – Neil – 2016-06-22T23:03:10.103

5

Python, 83 bytes

from datetime import*
lambda x:datetime.strptime(x,'%Y%m').strftime('%b%y').upper()

atlasologist

Posted 2016-06-22T19:58:22.717

Reputation: 2 945

I just posted an answer nearly identical to yours. I didn't see yours because it took a while to write the answer. If you want me to delete mine, I will, or you can use mine to get some extra bytes off. – jqblz – 2016-06-22T20:32:15.690

1That's fine, you beat me by 13 bytes, I'll concede. I like your manual answer, too. – atlasologist – 2016-06-22T20:45:57.950

5

Kotlin, 100 bytes

fun f(d:String)=SimpleDateFormat("MMMyy").format(SimpleDateFormat("yyyyMM").parse(d)).toUpperCase()

Pretty straight forward use of Java SimpleDateFormat

Rames

Posted 2016-06-22T19:58:22.717

Reputation: 221

1Hmm, I don't know Kotlin, but since it's derived from Java, shouldn't you include the import of the SimpleDateFormat (i.e. import java.text.*;)? – Kevin Cruijssen – 2016-06-23T07:10:51.000

Since the challenge asks for output, I would assume a print is required as part of your function. – JohnWells – 2018-04-06T21:48:41.610

5

MATLAB / Octave, 42 bytes

@(x)upper(datestr(datenum(x,'yyyymm'),12))

Creates an anonymous function named ans that is called with a string representing the date: ans('201604').

Online Demo

This solution uses datenum to convert the input date to a serial date number, and then datestr with the predefined output spec of mmmyy (12) to yield the string representation in the required format. Finally, we use upper to change it to MMMYY since the uppercase month is not an output option.

Suever

Posted 2016-06-22T19:58:22.717

Reputation: 10 257

1Wow, gj on beating everyone else in a non-golfing language! – Downgoat – 2016-06-22T20:44:50.670

4

JavaScript ES6, 77 66 bytes

Saved 11 bytes thanks to @Bálint!

a=>(new Date(0,a[4]+a[5]-1)+"").slice(4,7).toUpperCase()+a[2]+a[3]

Get's the date by extracting the string returned by the Date class. then capitalizes and adds the year.

ES5 version:

var a = prompt("Enter YYYYMM: ");
result = (new Date(0,a[4]+a[5]-1)+"").slice(4,7).toUpperCase()+a[2]+a[3]
alert(result);

Downgoat

Posted 2016-06-22T19:58:22.717

Reputation: 27 116

I made one in 66 bytes with the same atob technique, but I can't copy it out – Bálint – 2016-06-22T20:34:54.683

@Bálint I thought I got 66 bytes too but turns our byte counter was wrong due to to bad copy pasting ;) – Downgoat – 2016-06-22T20:36:53.057

You could get the month's name with (Date(0,a[4]- -a[5])+"").substr(4,3) – Bálint – 2016-06-22T21:09:31.540

Or (new Date(0,a[4]- -a[5])+"").substr(4,3) – Bálint – 2016-06-22T21:10:16.553

@Bálint oh wow, thanks! That's short! – Downgoat – 2016-06-22T22:29:19.403

1I don't get that a[4]- -a[5]. What was wrong with a[4]+a[5]-1? – Neil – 2016-06-22T22:55:34.143

You can cut one more character by turning (new Date(0,a[4]- -a[5])+"") to (new Date(0,a[4]- -a[5])+1) – eithed – 2016-06-22T23:01:00.860

Also - just doing new Date(a[4]+a[5]) generates valid month (at least in Chrome) – eithed – 2016-06-22T23:26:54.073

Wrong for me 201604 -> MAY16 – edc65 – 2016-06-23T14:44:44.130

@edc65 Whoops should be fixed now – Downgoat – 2016-06-23T17:20:48.300

@Guedes yeah >_> the months were one off fixed in same number of bytes by just subtracting one – Downgoat – 2016-06-23T17:21:52.303

Nice work. My first impulse was to do it all with strings, but the shortest I could make it was still 76 bytes: d=>'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'.substr(d.slice(4)*3-3,3)+d[2]+d[3] – nnnnnn – 2016-06-25T05:42:23.933

1new Date(0,a[4]+a[5]-1)+"" => new Date(0,a[4]+a[5]-1)+0 – l4m2 – 2018-04-07T00:53:38.837

a[4]+a[5]-1 => a%100-1 – l4m2 – 2018-04-08T13:53:17.153

4

Julia, 57 56 53 bytes

s->uppercase(Dates.format(DateTime(s,"yyyym"),"uyy"))

This is an anonymous function that accepts a string and returns a string. To call it, assign it to a variable.

First we construct a DateTime object using the type constructor and a format string. Note that the single m in the format string will get both one- and two-digit months, though the former case is irrelevant here. Since no days are specified, the first of the month is assumed.

We can then format the value as a string using the Dates.format function from the Base.Dates submodule. The string uyy gets the three-letter month name and two-digit year, but the result is in title case, e.g. Apr16 instead of the desired APR16, so we need to uppercase it.

Try it online! (includes all test cases)

Alex A.

Posted 2016-06-22T19:58:22.717

Reputation: 23 761

4

C, 147 145 112 bytes

main(m){char a[99]="JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";scanf("%4s%d",a+50,&m);printf("%.3s%s",a+--m*3,a+52);}

Online demo

Thanks ugoren!

Marco

Posted 2016-06-22T19:58:22.717

Reputation: 581

2Some cheap tricks - delete the #include, define m as a parameter - main(m), – ugoren – 2016-06-23T15:07:23.750

2Also, the %.3s format saves the null termination. – ugoren – 2016-06-23T15:09:12.510

Thanks @ugoren! I also changed "%4s%2d" to "%4s%d". – Marco – 2016-06-23T16:00:29.737

main(m){char a[9];scanf("%4s%d",a,&m);printf("%.3s%s","JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"+--m*3,a+2);} lot shorter – l4m2 – 2018-04-08T13:49:38.950

3

Japt, 35 34 bytes

ÐUr$/..../$,"$&-")+P s4,7 u +Us2,4

Link.

Uses the same technique as my JavaScript answer.

nicael

Posted 2016-06-22T19:58:22.717

Reputation: 4 585

3

Java 8, 154 113 bytes

import java.text.*;s->new SimpleDateFormat("MMMyy").format(new SimpleDateFormat("yyyyMM").parse(s)).toUpperCase()

Explanation:

Try it online.

import java.text.*;                 // Required import for SimpleDateFormat
s->                                 // Method with String as both parameter and return-type
  new SimpleDateFormat("MMMyy")     //  Create a formatter with format "MMMyy"
   .format(                         //  Format the following:
     new SimpleDateFormat("yyyyMM") //   Create another formatter with format "yyyyMM"
     .parse(s))                     //   Parse the input with this format
  .toUpperCase()                    //  Convert everything to Uppercase and return

Kevin Cruijssen

Posted 2016-06-22T19:58:22.717

Reputation: 67 575

I think you can shorten it if you remove the import and instead directly refer to it with java.text.SimpleDateFormat. – Frozn – 2016-06-23T14:22:30.157

2@Frozn Actually, import java.text.*; is 19 bytes, and two times java.text. in front of both SimpleDateFormat is 20 bytes. So it would increase by 1 byte instead of lowering it. – Kevin Cruijssen – 2016-06-23T14:53:47.440

Oh yea you're right. I always look at the ungolfed version and think that it's equal to the golfed one. Sorry :) – Frozn – 2016-06-25T09:50:38.480

@Frozn Ah, also a bit my bad. Usually I still use .*; for the ungolfed code, but this time I seem to have neglected it. I have save options that automatically converts it to pure imports since I use Java in my job, and I simply forgot to change it to import java.text.*;.. – Kevin Cruijssen – 2016-06-25T10:32:49.120

3

C#, 94 87 bytes

string C(string s)=>System.DateTime.Parse(s.Insert(4,"-")).ToString("MMMyy").ToUpper();

Saved 7 bytes by using C#6 Syntax.

Try Online

raznagul

Posted 2016-06-22T19:58:22.717

Reputation: 424

You can leave off return type information for lambdas, i.e C(string s)=>... – cat – 2016-06-24T17:58:00.720

2

Pyth, 45 bytes

+:."AYw2ûDÈëKH§È¼DYÉx\E±oË"J*3sgz5+3J:z2 4

Try it online!

Explanation:

+:."AYw2ûDÈëKH§È¼DYÉx\E±oË"J*3sgz5+3J:z2 4
                                z           Take the input
                               g 5          Slice inclusively from index 5 to the end
                              s             Parse as an int
                            *3              Multiply by 3
                           J                Store in variable J, this also returns J
 :                                          Take a slice
  ."AYw2ûDÈëKH§È¼DYÉx\E±oË"                 Of this packed string
                           J*3sgz5          From the J we defined before
                                  +3J       To J+3
+                                           To this string, append
                                     :z     A slice of the index
                                       2 4  From [2,4).

The packed string contains "JANJANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC". The two JANs are so that I can index it pseudo-one-indexed.

EDIT: Fixed bug that was messing with TIO

ericeschnei

Posted 2016-06-22T19:58:22.717

Reputation: 71

2

R, 65 bytes

function(A)paste0(toupper(month.abb[el(A:1)%%100]),substr(A,3,4))

Try it online!

Takes input as a string, leverages the constant month.abb. Uses modulus and substr to extract relevant values.

JayCe

Posted 2016-06-22T19:58:22.717

Reputation: 2 655

clever use of : to convert to integer! – Giuseppe – 2018-08-22T20:47:18.803

@Giuseppe Not my idea :) I took it from here. I can probably apply it to a number of my existing answers!

– JayCe – 2018-08-22T20:51:19.187

@Giuseppe I just found a shorter hack using el - 1 less byte. – JayCe – 2018-08-22T20:54:32.637

2

Oracle SQL, 49 Bytes

select to_char(to_date(n,'yyyymm'),'MONyy')from t

The data must be inserted in a table called T with a column N of type VARCHAR2(6), CHAR(6) or , only if all the years are > 1000, NUMBER

Usage:

drop table t;
create table t (n VARCHAR2(6));
insert into t values ('201604');
insert into t values ('200001');
insert into t values ('000112');
insert into t values ('123405');    

select to_char(to_date(n,'yyyymm'),'MONyy')from t;

Giacomo Garabello

Posted 2016-06-22T19:58:22.717

Reputation: 1 419

Would it be possible to use PRINT instead of SELECT and not refer to the table using a variable as input instead ? Declaring input variable and assigning the value does not affect the byte count – t-clausen.dk – 2016-06-23T12:37:02.230

Is it allowed to take input from a table? The codegolf tag info suggests that no.

– pajonk – 2016-06-23T13:38:57.363

@t-clausen.dk the shortest way using print is 58 chars: begin:n:=to_char(to_date(:n,'yyyymm'),'monyy');end;print n and you need 42 extra chars for a single input(VARIABLE n varchar2;BEGIN:n:='201605';END;) instead of 31 (insert into t values('000112');) if you have shorter ways please tell me. – Giacomo Garabello – 2016-06-23T13:39:32.493

@pajonk in this answer nobody tell me anything about the use of tables

– Giacomo Garabello – 2016-06-23T13:41:41.613

1

@pajonk according to this, you can use tables for input

– t-clausen.dk – 2016-06-23T13:47:13.233

Ok, just wanted to know. Thanks for clarification. – pajonk – 2016-06-23T17:01:49.467

2

Microsoft SQL Server, 57 Bytes

SELECT UPPER(FORMAT(CAST('201601'+'01' AS DATE),'MMMyy'))

The Upper function is required as format does not produce Upper case months as would be expected with the MMM format pattern.

Usage:

drop table t;
create table t (n VARCHAR(6));
insert into t values ('201604');
insert into t values ('200001');
insert into t values ('000112');
insert into t values ('123405');    

SELECT UPPER(FORMAT(CAST(n+'01' AS DATE),'MMMyy')) FROM t

N.Y

Posted 2016-06-22T19:58:22.717

Reputation: 21

Just saw your answer, it is alot like mine, didn't notice it until now, removed my answer – t-clausen.dk – 2016-06-23T12:23:36.337

Is it allowed to take input from a table? The codegolf tag info suggests that no.

– pajonk – 2016-06-23T13:38:28.517

@pajonk the answer here doesn't use input from a table, the answer is the top line and the input variable is hardcoded. Note that you can use tables as input variables as i mention earlier. The bottom part is an example how to convert several values. TSQL doesn't have STDIN nor input statements. Only way of adding data is using variables or tables. All of my answers are using those for input – t-clausen.dk – 2016-06-23T14:20:53.673

Ok, thanks for clarifying. – pajonk – 2016-06-23T17:03:12.500

1

Microsoft Excel VBA, 48 Bytes

Anonymous VBE immediate window function that takes input from range [A1] and outputs to the VBE immediate window

?UCase(MonthName([Right(A1,2)],1))+[Mid(A1,3,2)]

Current version thanks to input from @Engineer Toast, for pointing out the abbreviate option of the MonthName function.

Previous Version

?UCase(Format(DateSerial([Left(A1,4)],[Right(A1,2)],1),"MMMYY"))

Taylor Scott

Posted 2016-06-22T19:58:22.717

Reputation: 6 709

Worth noting that Excel needs to be set to English, otherwise it returns locale-specific month name. – pajonk – 2018-04-07T11:15:20.160

48 bytes: ?UCase(MonthName(Right([A1],2),1))&Mid([A1],3,2) – Engineer Toast – 2018-04-09T19:22:48.407

Turns out the Excel formula can be 46 bytes: =UPPER(TEXT(RIGHT(A1,2)*28,"MMM"))&MID(A1,3,2) – Engineer Toast – 2018-04-09T19:27:56.307

1

SmileBASIC, 85 bytes

DEF C D?MID$(@__JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC,VAL(D[4]+D[4])*3,3);D[2];D[3]END

@__JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC is equivalent to the string literal "@__JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC". JAN starts at index 3, so the program can calculate the position as month*3 instead of (month-1)*3 or month*3-3.

12Me21

Posted 2016-06-22T19:58:22.717

Reputation: 6 110

1

C# - 75 Bytes

s=>{return new System.DateTime(s/100,s%100,1).ToString("MMMyy").ToUpper();}

Romen

Posted 2016-06-22T19:58:22.717

Reputation: 161

1

K4, 65 59 bytes

Solution:

@[13 3#"DECJANFEBMARAPRMAYJUNJULAUGSEPOCTNOV";.*|x],*x:2 4_

Examples:

q)k)@[13 3#"DECJANFEBMARAPRMAYJUNJULAUGSEPOCTNOV";.*|x],*x:2 4_"201604"
"APR16"
q)k)@[13 3#"DECJANFEBMARAPRMAYJUNJULAUGSEPOCTNOV";.*|x],*x:2 4_"200001"
"JAN00"
q)k)@[13 3#"DECJANFEBMARAPRMAYJUNJULAUGSEPOCTNOV";.*|x],*x:2 4_"000112"
"DEC01"
q)k)@[13 3#"DECJANFEBMARAPRMAYJUNJULAUGSEPOCTNOV";.*|x],*x:2 4_"123405"
"MAY34"

Explanation:

Reshape the months of the year so that 0 => DEC and 1 => JAN ... 12 => DEC.

@[13 3#"DECJANFEBMARAPRMAYJUNJULAUGSEPOCTNOV";.*|x],*x:2 4_ / the solution
                                                       2 4_ / cut input at indices 2 & 4, "201604" => ["16", "04"]
                                                     x:     / save as x
                                                    *       / take first
                                                   ,        / join with
@[                                           ;    ]         / apply @[list;index]
                                               *|x          / reverse (|), first (*) aka 'last'
                                              .             / value ("05" => 5)
       "DECJANFEBMARAPRMAYJUNJULAUGSEPOCTNOV"               / offset months of the year
  13 3#                                                     / reshape

Bonus:

60 byte version in K (oK):

((13 3#"DECJANFEBMARAPRMAYJUNJULAUGSEPOCTNOV")@.*|x),*x:2 4_

Try it online!

streetster

Posted 2016-06-22T19:58:22.717

Reputation: 3 635

1

MediaWiki Template (with ParserFunctions), 29 bytes

{{uc:{{#time:My|{{{1}}}01}}}}

Only works if English locale is chosen.

Try Sandbox

tsh

Posted 2016-06-22T19:58:22.717

Reputation: 13 072

1

Caché ObjectScript - 65 bytes

Golfed

r i s d=$zcvt($zd($zdth(i_"01",8),6),"u") w $e(d,1,3)_$e(d,*-1,*)

Ungolfed

r i                            ; Read stdin and store into 'i'                      [200203]
   s d=                        ; Set the variable 'd' to the following...
       $zcvt(                  ; Convert the string
             $zd(              ; Parse the string as a caché date
                 $zdth(        ; Convert the date to horolog format (# days from 12/31/1840)
                       i_"01", ; Append the string "01" to variable 'i'             [20020301]
                       8       ; Use format #8 - "YYYYMMDD" (e.g. 20020301)
                      ),                                                            [58864,0]
                 6             ; Use format #6 - "Mmm [D]D YYYY" (e.g. Mar 1 2002)
                ),                                                                  [Mar 1 2002]
             "u"               ; Convert the string to uppercase
            )                                                                       [MAR 1 2002]
   w                           ; Write out the following...
     $e(d,1,3)                 ; Extract the substring from position 1 to 3 (inclusive) [MAR]
     _                         ; Concatenate
     $e(d,                     ; Extract the substring...
        *-1,                   ; ...from 1 character from the end of the string     [0]
        *                      ; ...to the last character                           [2]
       )                                                                            [02]
                                                                                    [MAR02]

Commentary

I don't think I've ever seen another Caché answer on this site. I'm only forced to know the language because of work (legacy code), but language itself is very powerful.

Some notes about the language:

  • Caché doesn't really care about whitespace, so r x r y is the same as r x \n r y
  • Each function is the shortname for the longer version:
    • r == read
    • s == set
    • $zcvt == $zconvert
    • $zd == $zdate
    • $zdth == $zdateh
    • $e == $extract
  • Arrays are 1-indexed

Unfortunately, there is no online interpreter for Caché. Probably either because it's too obscure or maybe a licensing thing.

If you're interested in the language, you can check out their docs on their very 90's looking website :)

homersimpson

Posted 2016-06-22T19:58:22.717

Reputation: 281

1

Perl 5 -p, 69 bytes

$_=(1,JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC)[/..$/g].$`%100

Try it online!

Xcali

Posted 2016-06-22T19:58:22.717

Reputation: 7 671

1

J, 70 bytes

4(}.((,~(_3]\'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'){~1-~".)~2&}.){.)]

Usage

   f =: 4(}.((,~(_3]\'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'){~1-~".)~2&}.){.)]
   f '201604'
APR16
   f '200001'
JAN00
   f '000112'
DEC01
   f '123405'
MAY34

Explanation

4(}.((,~(_3]\'...'){~1-~".)~2&}.){.)] Input: s
                                    ] Identity function, gets the value s
4                                     The constant 4
                                 {.   Take the first 4 chars from s
                            2&}.      Drop the first 2 (Take the last 2) to get the year
  }.                                  Drop the first 4 chars from s to get the month
                        ".            Parse the month substring as a number
                     1-~              Subtract 1 from it
             '...'                    List of MMM month names
         _3]\                         Split the list into nonoverlapping sublists of size 3
      ,~                              Join the MMM month name with the year and return

miles

Posted 2016-06-22T19:58:22.717

Reputation: 15 654

1

Pyth, 39 bytes

Hexdump:

0000000: 2b 40 63 2e 22 41 59 12 56 0a 7c bd 93 e3 1c 07 +@c."AY.V.|.....
0000010: e3 d4 d9 ed 5b 49 02 cd b4 92 83 86 22 33 73 3e ....[I......"3s>
0000020: 32 7a 3a 7a 32 20 34                            2z:z2 4

Test suite.

Leaky Nun

Posted 2016-06-22T19:58:22.717

Reputation: 45 011

1

jq, 35 characters

(34 characters code + 1 character command-line option.)

(Just tried whether the ^ trick used by Digital Trauma in his Bash answer works in jq too. Works. Now you know who inspired the most important character of this answer. (The alternative is to use the ascii_upcase function.))

strptime("%Y%m")|strftime("%^b%y")

Sample run (Option -R used only in this sample to pass all test cases.)

bash-4.3$ jq -Rr 'strptime("%Y%m")|strftime("%^b%y")' <<END
201604
200001
000112
123405
END
APR16
JAN00
DEC01
MAY34

On-line test: (Passing -R through URL is not supported – so input passed as JSON string literal. Passing -r through URL is not supported – check Raw Output yourself.)

manatwork

Posted 2016-06-22T19:58:22.717

Reputation: 17 865

1

R, 154 150 114 112 bytes

Takes six digit input into "b", separates the first four digits from the last two digits, abbreviates the 2-digit month and makes it uppercase, and concatenates it with the 3rd and 4th digit.

Golfed:

function(b){h=substr;i=sprintf;o="%06d";cat(toupper(month.abb[as.numeric(h(i(o,b),5,6))]),h(i(o,b),3,4),sep="")}

Ungolfed:

function(b){
   h=substr;i=sprintf;o="%06d";

   cat(
      toupper(month.abb[as.numeric(h(i(o,b),5,6))]),
      h(i(o,b),3,4),
   sep="")
}

EDITS: replaced duplicitous names with variables; fixed me being stupid. -2 bytes by turning function anonymous (thanks, cat).

a soft pillow

Posted 2016-06-22T19:58:22.717

Reputation: 131

Nice answer! You can leave off the a= for an anonymous function – cat – 2016-06-24T17:56:44.480

@cat I'm not too familiar with anonymous functions but wouldn't I need to add parentheses at the beginning and end of the function if I removed the a= ? Something like this: (function(m) {a=3;m*a})(10) – a soft pillow – 2016-06-24T18:52:44.893

1Nope, function(b){h=substr;i=sprintf;o="%06d";cat(toupper(month.abb[as.numeric(h(i(o,b),5,6))]),h(i(o,b),3,4),sep="")} is a function object all on its own. – cat – 2016-06-24T19:17:02.177

This doesn't appear to work. on RStudio with R 3.2.3 (2015-12-10) I get Error in i(o, b) : invalid format '%06d'; use format %s for character objects – cat – 2016-06-24T19:18:29.933

@cat Darn new versions messing everything up! I'm on RStudio running R version 3.1.1 (2014-07-10) and it works fine. How does this work here, should I get the new version and change up the code? Also thanks for the anonymous function tip! – a soft pillow – 2016-06-24T19:44:56.080

@cat this also works on R version 3.2.2 (2015-08-14) – a soft pillow – 2016-06-25T13:45:58.727

I've edited your post to include data about the version – cat – 2016-06-25T13:48:02.007

@cat it works perfectly well on R 3.2.5. The call to the function (if saved as function f) should be f(200612). The error you got implies you tried f("200612") instead. – plannapus – 2016-08-04T16:49:19.640

1

PHP, 78 bytes

<?=fscanf(STDIN,"%4d%d",$y,$m)?strtoupper(date("My",mktime(0,0,0,$m,1,$y))):0;

The "year 2038 problem" may occur on some computers, as here. But not in others, as here.

Marco

Posted 2016-06-22T19:58:22.717

Reputation: 581

@Titus, please don't try to edit other peoples' posts if there are problems and insert your own solutions; instead, please comment on the answer OR create a new answer yourself. – Value Ink – 2016-06-25T07:32:20.117

1

Factor, 82 78 bytes

[ [ 2 tail* 10 base> month-abbreviation ] [ 4 head 2 tail ] bi append >upper ]

Eshplained:

[                    ! new anonymouse function block (quotation)
  [                  ! new quotation 
    2 tail*          ! "201604" -> "04"
    10 base>         ! "04"     -> 4
    month-abbreviation ! 4 -> "Apr"
  ]                  ! end quotation
  [                  ! new quotation
    4 head           ! "201604" -> "2016"
    2 tail           ! "2016"   -> "16" 
  ]                  ! end quotation
  bi                 ! bifurcate two quotations to TOS
  append             ! "Apr" "16" -> "Apr16"
  >upper             ! "Apr16"    -> "APR16"
]                    ! end quotation

cat

Posted 2016-06-22T19:58:22.717

Reputation: 4 989

1

Swift 2.2, 149 bytes

let f = NSDateFormatter(),g = NSDateFormatter();f.dateFormat = "yyyyMM";g.dateFormat = "MMMyy"
g.stringFromDate(f.dateFromString(i)!).uppercaseString

Trying to get this shorter than Kotlin... It's a shame NSDateFormatter doesn't have an initializer that sets its dateFormat. NSDateFormatter also does not have a default dateFormat value, causing additional losses.

Swift 3, 136 bytes

let f = DateFormatter(),g = DateFormatter();f.dateFormat = "yyyyMM";g.dateFormat = "MMMyy"
g.string(from: f.date(from: i)!).uppercased()

Thanks to the removal of the NS prefix on some classes, I was able to make the Swift 3 answer a little shorter. Still not shorter than Kotlin though...

Test function and cases:

import Foundation
import XCTest

func dateConverter(i: String) -> String? {
    let f = DateFormatter(),g = DateFormatter();f.dateFormat = "yyyyMM";g.dateFormat = "MMMyy"

    if let date = f.date(from: i) {
        return g.string(from: date).uppercased()
    }

    return nil
}

XCTAssert(dateConverter(i: "201604") == "APR16")
XCTAssert(dateConverter(i: "200001") == "JAN00")
XCTAssert(dateConverter(i: "000112") == "DEC01")
XCTAssert(dateConverter(i: "123405") == "MAY34")

JAL

Posted 2016-06-22T19:58:22.717

Reputation: 304

0

dc, 103 bytes

[0n]sP[JAN][FEB][MAR][APR][MAY][JUN][JUL][AUG][SEP][OCT][NOV][DEC]Csi[lid1-si:mz1<M]dsMxA0~;mPA0~dZ2>Pp

Try it online!

[0n]sP is a macro that just prints a 0 w/o a newline for the sake of padding 1-9.

[JAN]...[DEC] places the strings on the stack. Csi[lid1-si:mz1<M]dsMx is a macro that decrements i from 12, popping the strings off of the stack and placing them at index i in the array m. Stops when one item (input) is left on the stack.

100~;mP does quotient/remainder division by 100, and prints the value from m indexed by the remainder. The quotient is left on the stack. 100~dZ2>Pp again gets the remainder after dividing by 100, runs the padding macro P this is one digit long, and then prints.

Without any way of manipulating strings, I don't think that part is golfable. Doing any sort of wizardry with JAN/JUN/JUL would likely take far more bytes than the strings themselves.

brhfl

Posted 2016-06-22T19:58:22.717

Reputation: 1 291

0

Tcl, 98 bytes

proc C d {scan $d %2d%2d%2d d y m
format %s%02d [string tou [clock f [clock sc $m/1/0] -f %b]] $y}

Try it online!


Tcl, 115 bytes

proc C d {scan $d %2d%2d%2d d y m
format %s%02d [lindex {. JAN FEV MAR APR MAY JUN JUL AUG SEP OCT NOV DEC} $m] $y}

Try it online!


Tcl, 144 bytes

proc C d {scan $d %2d%2d%2d d y m
format %s%02d [string map {10 OCT 11 NOV 12 DEC 1 JAN 2 FEV 3 MAR 4 APR 5 MAY 6 JUN 7 JUL 8 AUG 9 SEP} $m] $y}

Try it online!

sergiol

Posted 2016-06-22T19:58:22.717

Reputation: 3 055

0

Python, 75 bytes

Here is my obvious Python lambda, takes and returns a string, hope I didn't miss some obvious hole:

lambda x:"JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"[3*int(x[4:])-3:][:3]+x[2:4]

FRex

Posted 2016-06-22T19:58:22.717

Reputation: 41

0

PHP, 55 bytes

<?=date(My,strtotime(wordwrap($argn,4,"-",1)))&"___??";

Run as pipe with -n or try it online. Requires PHP 5 or later.

Titus

Posted 2016-06-22T19:58:22.717

Reputation: 13 814

0

Base R, 78 bytes

paste(casefold(month.abb,upper=T)[strtoi(substr(A,5,6))],substr(A,3,4),sep="")

Not sure if this is required to be formatted as a standalone function, but if so, it is 91 bytes:

function(A){paste(casefold(month.abb,upper=T)[strtoi(substr(A,5,6))],substr(A,3,4),sep="")}

KamRa

Posted 2016-06-22T19:58:22.717

Reputation: 11

You will need to use the function, your first piece of code is called a snippet, and they are disallowed. I don't know much about R but you can also use a complete program or anonymous function if that helps. – Post Rock Garf Hunter – 2018-04-09T18:36:39.017

Thanks for the clarification. I'm new to this game. Is there a general documentation for the rules of the game? – KamRa – 2018-04-09T21:43:09.193

Yes there is. Note that these are just defaults so they can be overridden by individual challenges, however they rarely are. – Post Rock Garf Hunter – 2018-04-09T22:13:05.347

0

PHP, 146 Bytes.

Manipulating string

Code Try it online

function f($d){echo strtr(ltrim(substr($d,-2),'0'),array_combine(range(1,12),
str_split(JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC,3))).substr($d,2,-2);}

Explanation

function f($d){
                                #strtr allows u to set an array to replace the ocurrences
echo strtr(ltrim(substr($d,-2),'0'),        #Substring of the last two numbers of the input, 
                                           #removing leading zero
    array_combine(range(1,12),      
    str_split(JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC,3)))
                                           #create an array of ["1"=>JAN, "2"=>FEB...12=>DEC], 
                                           #split the string by 3 characters
    .substr($d,2,-2);
                                           #Concatenate the 2 middle characters
}

Francisco Hahn

Posted 2016-06-22T19:58:22.717

Reputation: 591

0

JavaScript ES6, 61 bytes

@Downgoat seems not there so I repost to optimize

a=>(new Date(0,a%100-1)+0).slice(4,7).toUpperCase()+a[2]+a[3]

l4m2

Posted 2016-06-22T19:58:22.717

Reputation: 5 985

0

C (tcc), 155 bytes

Longest answer here.

main(i){char*k,s[6],*a="JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";gets(s);strcpy(k,s+2);memset(k+2,0,2);i=atoi(s+4)*3;memset(a+i,0,i);strcat(k,a+i-3);puts(k);}

Try it online!

erdem

Posted 2016-06-22T19:58:22.717

Reputation: 41

Welcome to PPCG! :) – Shaggy – 2018-07-20T14:51:22.750

136 bytes – ceilingcat – 2019-08-20T00:32:21.297

0

C (gcc), 107 104 bytes

main(){char s[7];gets(s+1);write(1,memcpy(s,"JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"+~-atoi(s+5)*3,3),5);}

Try it online!

ceilingcat

Posted 2016-06-22T19:58:22.717

Reputation: 5 503

0

Batch, 148 bytes

@set d=%1
@for %%m in (JAN.01 FEB.02 MAR.03 APR.04 MAY.05 JUN.06 JUL.07 AUG.08 SEP.09 OCT.10 NOV.11 DEC.12)do @if %%~xm==.%d:~4% echo %%~nm%d:~2,2%

No date libraries to speak of so manual parsing ftw. I don't know whether the rules of Code Golf allow creating 12 appropriately-named files in the current directory, resulting in something like this:

@set d=%1
@for %%m in (*.%d:~4%)do @echo %%~nm%d:~2,2%

Neil

Posted 2016-06-22T19:58:22.717

Reputation: 95 035

0

Ruby 46 + 6 for -rdate = 52

For completeness, if nothing else.

->d{Date.strptime(d,'%Y%m').strftime('%^b%y')}

See the tests on repl.it: https://repl.it/Cj7z

Jordan

Posted 2016-06-22T19:58:22.717

Reputation: 5 001

The closest I could get without rdate was 70 bytes, so this looks like the winning tactic for Ruby. – benj2240 – 2018-04-06T20:12:21.463

0

T-SQL, 96 bytes

declare @i varchar(8)
select  @i = '201604'
select upper(left(datename(month,@i+'01'),3)) + substring(@i,5,2)

datagod

Posted 2016-06-22T19:58:22.717

Reputation: 151

0

Java, 142 bytes

s->(new String[]{"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"})[Integer.decode(s.substring(4))-1]+s.substring(2,4);

Shaun Wild

Posted 2016-06-22T19:58:22.717

Reputation: 2 329