56
\$\begingroup\$

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
\$\endgroup\$
2
  • 5
    \$\begingroup\$ This question is very well-balanced. Both manual parsing and date libraries end up being about the same, at least in Python. \$\endgroup\$ – jqblz Jun 22 '16 at 20:32
  • 10
    \$\begingroup\$ Yesterday, 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 :) \$\endgroup\$ – cat Jun 23 '16 at 14:30

54 Answers 54

1
2
1
\$\begingroup\$

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).

\$\endgroup\$
8
  • \$\begingroup\$ Nice answer! You can leave off the a= for an anonymous function \$\endgroup\$ – cat Jun 24 '16 at 17:56
  • \$\begingroup\$ @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) \$\endgroup\$ – a soft pillow Jun 24 '16 at 18:52
  • 1
    \$\begingroup\$ Nope, 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. \$\endgroup\$ – cat Jun 24 '16 at 19:17
  • \$\begingroup\$ 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 \$\endgroup\$ – cat Jun 24 '16 at 19:18
  • \$\begingroup\$ @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! \$\endgroup\$ – a soft pillow Jun 24 '16 at 19:44
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

C# - 75 Bytes

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

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!

\$\endgroup\$
1
\$\begingroup\$

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 :)

\$\endgroup\$
1
\$\begingroup\$

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"))
\$\endgroup\$
3
  • \$\begingroup\$ Worth noting that Excel needs to be set to English, otherwise it returns locale-specific month name. \$\endgroup\$ – pajonk Apr 7 '18 at 11:15
  • \$\begingroup\$ 48 bytes: ?UCase(MonthName(Right([A1],2),1))&Mid([A1],3,2) \$\endgroup\$ – Engineer Toast Apr 9 '18 at 19:22
  • \$\begingroup\$ Turns out the Excel formula can be 46 bytes: =UPPER(TEXT(RIGHT(A1,2)*28,"MMM"))&MID(A1,3,2) \$\endgroup\$ – Engineer Toast Apr 9 '18 at 19:27
1
\$\begingroup\$

Perl 5 -p, 69 bytes

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

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%
\$\endgroup\$
0
\$\begingroup\$

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

\$\endgroup\$
1
  • \$\begingroup\$ The closest I could get without rdate was 70 bytes, so this looks like the winning tactic for Ruby. \$\endgroup\$ – benj2240 Apr 6 '18 at 20:12
0
\$\begingroup\$

T-SQL, 96 bytes

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

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);
\$\endgroup\$
0
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

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]
\$\endgroup\$
0
\$\begingroup\$

PHP, 55 bytes

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

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

\$\endgroup\$
0
\$\begingroup\$

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!

\$\endgroup\$
3
0
\$\begingroup\$

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="")}
\$\endgroup\$
3
  • \$\begingroup\$ 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. \$\endgroup\$ – Wheat Wizard Apr 9 '18 at 18:36
  • \$\begingroup\$ Thanks for the clarification. I'm new to this game. Is there a general documentation for the rules of the game? \$\endgroup\$ – KamRa Apr 9 '18 at 21:43
  • \$\begingroup\$ Yes there is. Note that these are just defaults so they can be overridden by individual challenges, however they rarely are. \$\endgroup\$ – Wheat Wizard Apr 9 '18 at 22:13
0
\$\begingroup\$

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
}
\$\endgroup\$
0
\$\begingroup\$

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]

\$\endgroup\$
0
\$\begingroup\$

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!

\$\endgroup\$
2
  • \$\begingroup\$ Welcome to PPCG! :) \$\endgroup\$ – Shaggy Jul 20 '18 at 14:51
  • \$\begingroup\$ 136 bytes \$\endgroup\$ – ceilingcat Aug 20 '19 at 0:32
0
\$\begingroup\$

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!

\$\endgroup\$
0
\$\begingroup\$

Japt -P, 14 bytes

ÐUò4)Ť¤u ¸o¤ë

Try it

ÐUò4)Ť¤u ¸o¤ë     :Implicit input of string U          > "201604"
Ð                  :Create Date object from
 Uò4               :  Partitions of U of length 4       > ["2016","04"]
    )              :End Date
     Å             :To date string                      > "Fri Apr 01 2016"
      ¤            :Slice off the first 2 characters    > "i Apr 01 2016"
       ¤           :Slice off the first 2 characters    > "Apr 01 2016"
        u          :Uppercase                           > "APR 01 2016"
          ¸        :Split on spaces                     > ["APR","01","2016"]
           o       :Modify the last element
            ¤      :  Slice off the first 2 characters  > ["APR","01","16"]
             ë     :Get every second element            > ["APR","16"]
                   :Implicitly join and output          > "APR16"
\$\endgroup\$
0
\$\begingroup\$

Pyth, 42 bytes

Ac2>Q2+@c12."AY4H~0ë™~³!ò²×Œ¶7Ö"tiHTG

Try it online!

Ac2>Q2+@c12."AY4H~0ë™~³!ò²×Œ¶7Ö"tiHTG   // With Input '123405'

   >Q2                                       // Get input from index 2 (3405)
Ac2 ^                                        // Split it in two and assign to G and H (G='34', H='05'])
           ."AY4H~0ë™~³!ò²×Œ¶7Ö"             // Packed string representing: "JANFEBMAR..."
        c12."    JANFEBMAR...     "        // Chop it into 12 pieces (["JAN", "FEB", "MAR"...])
                                     tiHT    // Convert "05" to 5, subtract 1.
       @  ["JAN", "FEB", "MAR"...]   tiHT    // Get element at that index (MAY)
      +           "MAY"                  G   // "MAY" + 34
\$\endgroup\$
0
\$\begingroup\$

Groovy, 69 55 51 bytes

f={sprintf('%Tb',(it[4..5]as int)*22**7L)+it[2..3]}

Try it online!

This formats a millisecond value as an uppercase month name: sprintf('%Tb',value). The magic value of 22^7 is a value such that n * 22^7 milliseconds after epoch is in the nth month of the year of 1970. This value was derived by testing all possible 1 to 2 digit values. Therefore month * 22^7 will yield a value within that month.

  1. 1970-01-29
  2. 1970-02-27
  3. 1970-03-28
  4. 1970-04-26
  5. 1970-05-25
  6. 1970-06-23
  7. 1970-07-22
  8. 1970-08-19
  9. 1970-09-17
  10. 1970-10-16
  11. 1970-11-14
  12. 1970-12-13
\$\endgroup\$
0
\$\begingroup\$

Haskell, 85 bytes

f s=3`take`drop(read(drop 4s)*3-3)"JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"++[s!!2,s!!3]

Try it online!

\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.