4

I have been struggling to change the date format to US locale time. I tried so many methods but if fails at some or other scenario. The issue is I cannot say which Locale the client will be using. If anybody can help me it will be great.

I have tried the $A.localizationService.formatDate(sDate, "yyyy-MM-dd") but when the date comes like this '31.3.2018' it throws error. Even tried this as well new Date(sDate). it throws Invalid Date Error for date '31.3.2018' but it works if the date is less or equals to 12 suppose '10.2.2018' or '2.10.2018'.

So I tried to write a method which converts the date to "yyyy-MM-dd" format. So far what I have tried.

formatDate : function(date) {
    if(typeof(date) != 'string') {
        return $A.localizationService.formatDate(date, "yyyy-MM-dd");
    }

    if(date != null && date.search("-") > -1){
        return date;
    }

    var regex = /[^a-zA-Z0-9]/g;
    var specialcharacter = '-';

    date = date.replace(regex, specialcharacter);
    var dateparts = date.split(specialcharacter);

    if(dateparts == null || dateparts.length <= 1) {
        return $A.localizationService.formatDate(new Date(), "yyyy-MM-dd");
    }
    if(dateparts[0].length == 4){
        date = new Date(parseInt(dateparts[0]), parseInt(dateparts[1] - 1), parseInt(dateparts[2]));    
    }
    else{
        date = new Date(parseInt(dateparts[2]), parseInt(dateparts[1] - 1), parseInt(dateparts[0]));    
    }
    return $A.localizationService.formatDate(date, "yyyy-MM-dd");
}

anywhere in my controller.js I have passing date to the above function which converts the date to "yyyy-MM-dd" format. I tried with Finnish locale in Dev org it is working as expected but when we installed this on sandbox it was giving us the error.

Let me know if something else is required from my side.

1

Where is the date that you're trying to process coming from? From user input? Is there any constraint on its format?

I would never consider writing a date parser (or anything remotely like one) myself. If you start throwing regexes at a string that might be a date, you're going to be in for an endless world of pain as funny strings trip you up.

I'd split the problem into two steps:

  1. Take untrusted/unpredictable input and turn it into a JS Date object
  2. Output the JS Date in user's locale

Part (2) is easy. As in your code, you just use $A.localizationService.formatDate. Or maybe the <lightning:formattedDateTime> component.

Part (1) is where I would just go straight to using moment.js (https://momentjs.com/). If you know what format to expect, you can parse it like this:

var parsed = moment('31.3.2018', 'DD.MM.YYYY')

Standard ISO formats are simply like this:

var parsed = moment('2018-3-31')
  • Thanks for your input. Date is coming from user DB only. i guess I will not be able to use any third party js libraries. while searching for solution I came across the moment.js but not useful for me. I tried your step one but when I do $A.localizationService.formatDate for the date '31.3.2018' it throws error. – Nupur Bhagat Mar 14 '18 at 11:04
1

Some how I found the workaround for this solution.. This is not a full proof solution but it may be work as workaround.

<aura:attribute name="dateFormat" type="String" default="{!$Locale.dateFormat}"/>

This gives me the user's current locale date format. So I will try to parse the date using format.

formatDate : function(component, date) {
    if(typeof(date) != 'string') {
        return $A.localizationService.formatDate(date, "yyyy-MM-dd");
    }

    var regex = /[^a-zA-Z0-9]/g;
    var specialcharacter = '-';

    date = date.replace(regex, specialcharacter);
    var dateparts = date.split(specialcharacter);

    var dateFormat = component.get('v.dateFormat');
    dateFormat = dateFormat.replace(regex, specialcharacter);
    var dateFormatParts = dateFormat.split(specialcharacter);

    var dayIndex = 0;
    var monthIndex = 0;
    var yearIndex = 0;
    for(var i=0; i<dateFormatParts.length; i++) {
        if(dateFormatParts[i].includes('d') || dateFormatParts[i].includes('D')) {
            dayIndex = i;
        }
        if(dateFormatParts[i].includes('m') || dateFormatParts[i].includes('M')) {
            monthIndex = i;
        }
        if(dateFormatParts[i].includes('y') || dateFormatParts[i].includes('Y')) {
            yearIndex = i;
        }
    }
    date = date.replace(regex, specialcharacter);
    var dateparts = date.split(specialcharacter);

    date = new Date(parseInt(dateparts[yearIndex]), parseInt(dateparts[monthIndex] - 1), parseInt(dateparts[dayIndex])); 
    return $A.localizationService.formatDate(date, "yyyy-MM-dd");
}

user can call this function by passing the Component and Date. and it will change the date to "yyyy-MM-dd". User can change to other format as well. I wanted "yyyy-MM-dd" way. Hope this may help someone.

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.