# Convert YYYYMM to MMMYY

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

• This question is very well-balanced. Both manual parsing and date libraries end up being about the same, at least in Python. Jun 22, 2016 at 20:32
• 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 :)
– cat
Jun 23, 2016 at 14:30

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

• @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. Jun 25, 2016 at 7:32

# 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")


# R, 154150114 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).

• Nice answer! You can leave off the a= for an anonymous function
– cat
Jun 24, 2016 at 17:56
• @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) Jun 24, 2016 at 18:52
• 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.
– cat
Jun 24, 2016 at 19:17
• 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
Jun 24, 2016 at 19:18
• @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! Jun 24, 2016 at 19:44

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. # C# - 75 Bytes s=>{return new System.DateTime(s/100,s%100,1).ToString("MMMyy").ToUpper();}  # 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! # 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 :) ## 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,
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 }  # 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] # 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! • Welcome to PPCG! :) Jul 20, 2018 at 14:51 • 136 bytes Aug 20, 2019 at 0:32 # 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! # Perl 5-p, 69 bytes $_=(1,JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC)[/..$/g].$%100


Try it online!

# 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"


# 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


# 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

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


Try it online!

# Vyxalo, 37 bytes

4ȯI«×g~Þ¯p-Ḃ:u‹Ẇ¹²Ṗ¨€r;↓§%«3ẇ$‹i⇧₴4Ẏ∷  Try it Online! 4ȯI # Month as int «...«3ẇ # Compressed string of month names$‹i      # Get the correct month
⇧₴    # Uppercase and print
4Ẏ∷ # Get the last two digits of year


# Lua 5.3, 82 bytes

i=io.read()print(os.date("%b%y",os.time({year=i//100,month=i%100,day=1})):upper())


Needs to be run on an english machine, as the month name is language specific.

Version that works in any locale 91 bytes

i=io.read()j=i%100*3 print(("JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"):sub(j-2,j)..i:sub(3,4))


# JavaScript (Node.js), 78 bytes

i=>'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'.match(/.../g)[i[4]+i[5]-1]+i[2]+i[3]


Try it online!

# Scala, 85 bytes

s=>"JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC".drop(30*s(4)+3*s(5)-1587).take(3)+s(2)+s(3)


The index lookup 30*s(4)+3*s(5)-1587 is a golfed version (via ASCII arithmetics) of the more readable s.slice(4,6).toInt*3-3.

Try it online!

I also tried the nice trick by @cliffroot to represent the names of the months via Chinese characters. This gives the following variant that is 23 characters shorter (62 instead of 85), but at the end 1 byte longer (86 instead of 85):

s=>""+BigInt(""+"憯䷳烣㘿烪摿摽㛨近筍矯䏔"(10*s(4)+s(5)-528),36)+s(2)+s(3)

# Factor, 56 bytes

[ 2 tail 2 cut dec> months "%b"strftime >upper prepend ]


Try it online!

## Explanation

          ! "201604"
2         ! "201604" 2
tail      ! "1604"
2         ! "1604" 2
cut       ! "16" "04"
dec>      ! "16" 4
months    ! "16" T{ duration f 0 4 0 0 0 0 }
"%b"      ! "16" T{ duration f 0 4 0 0 0 0 } "%b"
strftime  ! "16" "Apr"
>upper    ! "16" "APR"
prepend   ! "APR16"


# Python, 115 bytes

m='JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC'.split();d=input();print("%s%s"%(m[int(d[4]+d[5])-1],d[2]+d[3]))


Try it online

• I suggest that you look into lambda functions and generally try to avoid use of split() - That said, I think that JQBLZ's manual string parsing answer may already be optimal for Py3 - you should take a look at that one Feb 6 at 21:13

## 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%


# 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

• The closest I could get without rdate was 70 bytes, so this looks like the winning tactic for Ruby. Apr 6, 2018 at 20:12
• -6? Feb 6 at 4:29

# T-SQL, 96 bytes

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


# 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);


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

# 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]


<?=date(My,strtotime(wordwrap($argn,4,"-",1)))&"___??";  Run as pipe with -n or try it online. Requires PHP 5 or later. # 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!

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!

• Failed outgolf: tio.run/##TY5NC4JAGITv/… Apr 6, 2018 at 23:41
• Apr 8, 2018 at 11:42
• Apr 8, 2018 at 11:44