Problem

Given a date string in the form Day Month Year, where:

  • Day is in the set {"1st", "2nd", "3rd", "4th", ..., "30th", "31st"}.
  • Month is in the set {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}.
  • Year is in the range [1900, 2100].

Convert the date string to the format YYYY-MM-DD, where:

  • YYYY denotes the 4 digit year.
  • MM denotes the 2 digit month.
  • DD denotes the 2 digit day.

Examples

Example 1

1
2
Input: date = "20th Oct 2052"
Output: "2052-10-20"

Example 2

1
2
Input: date = "6th Jun 1933"
Output: "1933-06-06"

Example 3

1
2
Input: date = "26th May 1960"
Output: "1960-05-26"

Constraints

  • The given dates are guaranteed to be valid, so no error handling is necessary.

Solution

Method 1 – String Parsing and Mapping

Intuition

We can split the date string into its parts, map the month abbreviation to its number, and format the day and month with leading zeros as needed.

Approach

  1. Split the input string into day, month, and year.
  2. Remove the suffix from the day and pad with zero if needed.
  3. Map the month abbreviation to its two-digit number.
  4. Concatenate year, month, and day in the required format.

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Solution {
public:
    string reformatDate(string date) {
        unordered_map<string, string> m = {
            {"Jan","01"},{"Feb","02"},{"Mar","03"},{"Apr","04"},{"May","05"},{"Jun","06"},
            {"Jul","07"},{"Aug","08"},{"Sep","09"},{"Oct","10"},{"Nov","11"},{"Dec","12"}
        };
        istringstream ss(date);
        string d, mon, y;
        ss >> d >> mon >> y;
        d = d.substr(0, d.size()-2);
        if (d.size() == 1) d = "0" + d;
        return y + "-" + m[mon] + "-" + d;
    }
};
1
2
3
4
5
6
7
func reformatDate(date string) string {
    months := map[string]string{"Jan":"01","Feb":"02","Mar":"03","Apr":"04","May":"05","Jun":"06","Jul":"07","Aug":"08","Sep":"09","Oct":"10","Nov":"11","Dec":"12"}
    parts := strings.Split(date, " ")
    d := parts[0][:len(parts[0])-2]
    if len(d) == 1 { d = "0" + d }
    return parts[2] + "-" + months[parts[1]] + "-" + d
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import java.util.*;
class Solution {
    public String reformatDate(String date) {
        Map<String, String> m = Map.of("Jan","01","Feb","02","Mar","03","Apr","04","May","05","Jun","06","Jul","07","Aug","08","Sep","09","Oct","10","Nov","11","Dec","12");
        String[] parts = date.split(" ");
        String d = parts[0].substring(0, parts[0].length()-2);
        if (d.length() == 1) d = "0" + d;
        return parts[2] + "-" + m.get(parts[1]) + "-" + d;
    }
}
1
2
3
4
5
6
7
8
9
class Solution {
    fun reformatDate(date: String): String {
        val months = mapOf("Jan" to "01", "Feb" to "02", "Mar" to "03", "Apr" to "04", "May" to "05", "Jun" to "06", "Jul" to "07", "Aug" to "08", "Sep" to "09", "Oct" to "10", "Nov" to "11", "Dec" to "12")
        val parts = date.split(" ")
        var d = parts[0].dropLast(2)
        if (d.length == 1) d = "0$d"
        return "${parts[2]}-${months[parts[1]]}-$d"
    }
}
1
2
3
4
5
6
class Solution:
    def reformatDate(self, date: str) -> str:
        months = {"Jan":"01","Feb":"02","Mar":"03","Apr":"04","May":"05","Jun":"06","Jul":"07","Aug":"08","Sep":"09","Oct":"10","Nov":"11","Dec":"12"}
        d, m, y = date.split()
        d = d[:-2].zfill(2)
        return f"{y}-{months[m]}-{d}"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
use std::collections::HashMap;
impl Solution {
    pub fn reformat_date(date: String) -> String {
        let months = [
            ("Jan","01"),("Feb","02"),("Mar","03"),("Apr","04"),("May","05"),("Jun","06"),
            ("Jul","07"),("Aug","08"),("Sep","09"),("Oct","10"),("Nov","11"),("Dec","12")
        ].iter().cloned().collect::<HashMap<_,_>>();
        let parts: Vec<&str> = date.split(' ').collect();
        let mut d = &parts[0][..parts[0].len()-2];
        if d.len() == 1 { d = &format!("0{}", d); }
        else { d = d; }
        format!("{}-{}-{}", parts[2], months[parts[1]], d)
    }
}
1
2
3
4
5
6
7
8
class Solution {
    reformatDate(date: string): string {
        const months: Record<string, string> = {Jan:"01",Feb:"02",Mar:"03",Apr:"04",May:"05",Jun:"06",Jul:"07",Aug:"08",Sep:"09",Oct:"10",Nov:"11",Dec:"12"};
        const [d, m, y] = date.split(' ');
        const day = d.slice(0, -2).padStart(2, '0');
        return `${y}-${months[m]}-${day}`;
    }
}

Complexity

  • ⏰ Time complexity: O(1), since the input is always a single date string of bounded length.
  • 🧺 Space complexity: O(1), as only a few variables and a fixed mapping are used.