Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1853. Convert Date Format - Leetcode Solution

Code Implementation

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'
        }
        day, month, year = date.split()
        day = day[:-2].zfill(2)
        month = months[month]
        return f"{year}-{month}-{day}"
      
class Solution {
public:
    string reformatDate(string date) {
        unordered_map<string, string> 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"}
        };
        istringstream iss(date);
        string day, month, year;
        iss >> day >> month >> year;
        day = day.substr(0, day.size() - 2);
        if (day.size() == 1) day = "0" + day;
        return year + "-" + months[month] + "-" + day;
    }
};
      
class Solution {
    public String reformatDate(String date) {
        Map<String, String> months = new HashMap<>();
        months.put("Jan", "01"); months.put("Feb", "02"); months.put("Mar", "03"); months.put("Apr", "04");
        months.put("May", "05"); months.put("Jun", "06"); months.put("Jul", "07"); months.put("Aug", "08");
        months.put("Sep", "09"); months.put("Oct", "10"); months.put("Nov", "11"); months.put("Dec", "12");
        String[] parts = date.split(" ");
        String day = parts[0].substring(0, parts[0].length() - 2);
        if (day.length() == 1) day = "0" + day;
        String month = months.get(parts[1]);
        String year = parts[2];
        return year + "-" + month + "-" + day;
    }
}
      
var reformatDate = function(date) {
    const 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"
    };
    let [day, month, year] = date.split(" ");
    day = day.slice(0, -2).padStart(2, '0');
    return `${year}-${months[month]}-${day}`;
};
      

Problem Description

You are given a string date representing a date in the format "Day Month Year", where:

  • Day is a number from 1 to 31, followed by a two-letter ordinal suffix (e.g., "1st", "2nd", "3rd", "4th", ... "31st").
  • Month is a three-letter English abbreviation ("Jan", "Feb", ..., "Dec").
  • Year is a 4-digit number.
Your task is to convert date into the format "YYYY-MM-DD", where:
  • Year is 4 digits (unchanged)
  • Month is two digits, zero-padded if necessary
  • Day is two digits, zero-padded if necessary
Constraints: The input string is always valid. You do not need to handle invalid dates or ambiguous cases.

Thought Process

The problem is about reformatting a date string from a human-readable form to an ISO-like format. At first glance, you might think of parsing the string character by character or using regular expressions. But since the format is always consistent and valid, we can approach it more simply:

  • Split the input string by spaces to separate the day, month, and year.
  • Remove the ordinal suffix from the day and pad it with a leading zero if it's a single digit.
  • Map the month abbreviation to its corresponding two-digit number.
  • Combine the parts in the required order.
The brute-force approach would be to check every character or use regex, but since the format is fixed, splitting and mapping is more efficient and readable.

Solution Approach

Let's break down the steps to solve the problem:

  1. Split the String: Use the space character to split date into three parts: day, month, and year.
  2. Process the Day: The day part contains a number and a suffix (e.g., "20th"). Remove the last two characters to get the number, then pad it with a leading zero if it's only one digit (e.g., "3" becomes "03").
  3. Map the Month: Create a mapping from month abbreviations to their two-digit representations (e.g., "Jan" → "01"). Use this mapping to convert the month part.
  4. Assemble the Result: Combine the year, month, and day in the "YYYY-MM-DD" format.
Why use a mapping? Since there are only 12 months, a dictionary (hash map) provides quick O(1) lookups, making the conversion efficient.

Example Walkthrough

Example Input: date = "20th Oct 2052"
Step-by-step process:

  • Split by spaces: ["20th", "Oct", "2052"]
  • Day: "20th" → remove last two characters → "20" (already two digits)
  • Month: "Oct" → mapped to "10"
  • Year: "2052"
  • Combine: "2052-10-20"
Another Example: date = "6th Jun 1933"
  • Split: ["6th", "Jun", "1933"]
  • Day: "6th" → "6" → pad to "06"
  • Month: "Jun" → "06"
  • Year: "1933"
  • Combine: "1933-06-06"

Time and Space Complexity

Brute-force approach: If you attempted to parse character by character or use regex, the time complexity would still be O(1) since the length of the string is bounded and small.
Optimized approach:

  • Time Complexity: O(1) — All operations (splitting, mapping, string manipulation) are constant time due to small input size.
  • Space Complexity: O(1) — The mapping for months is constant in size (12 entries), and we only use a few variables for processing.
The solution is optimal for this problem due to the fixed, small input domain.

Summary

To convert a date from a human-readable format with ordinal days and abbreviated months to an ISO-like format, we:

  • Split the string into day, month, and year
  • Trim and pad the day as needed
  • Map the month abbreviation to a two-digit number
  • Assemble the result in the required format
This approach is elegant because it leverages the predictable structure of the input and uses a simple mapping for months, resulting in a concise, efficient solution.