John Lamb
John Lamb

Reputation: 21

moment js displays milliseconds after AM/PM

Currently working on a project that deals with different languages and ran into a weird behavior when displaying milliseconds in the PM/AM format.

If I want to display a date/time pair with millisecond precision using the AM/PM format I get something like this:

12/14/2017 3:45:45 PM.199

Whereas the same date/time in a 24h format is shown like this:

12/14/2017 15:45:45.199

Is there a way to display the AM/PM format like this:

12/14/2017 3:45:45.199 PM

The objective is to dislpay the date/time according to the users localization options, that is why I'm using the "L LTS" formatting.

Here is a fiddle to illustrate the problem

var divEn = $('#divEn');
var divFi = $('#divFi');
var en = "en";
var pt = "pt";
var dateEn = moment().locale(en);
var dateFi = moment().locale(pt);
format = "L LTS.SSS";
divEn.text(dateEn.format(format));
divFi.text(dateFi.format(format)); 

Upvotes: 1

Views: 24797

Answers (1)

VincenzoC
VincenzoC

Reputation: 31482

If you always want to display result like 12/14/2017 3:45:45.199 PM use MM/DD/YYYY h:mm:ss.SSS A as format token instead of L LTS.SSS.

MM stands for number of month, DD is day of the month, YYYY is the year, h is the hour (0..12), mm stands for minutes, ss stands for seconds, SSS stands for fractional second and A stands for AM/PM.

L and LTS are localized tokens (output varies based on locale).

EDIT:

You can use localeData() and longDateFormat() go get localized format token, then you can check if the LTS token contains the AM/PM token (A or a) and change the format dinamically.

Here a live sample:

function getCustomLocalizedFormat(locale){
  var localeData = moment.localeData(locale);
  var lts = localeData.longDateFormat('LTS');
  var format = "L LTS.SSS";
  if( lts.match(/a/i) ){
    format = "L h:mm:ss.SSS A";
  }
  return format;
}

var divEn = $('#divEn');
var divFi = $('#divFi');
var divRes = $('#divRes');
var en = "en";
var pt = "pt";
var dateEn = moment().locale(en);
var dateFi = moment().locale(pt);

var enLocaleData = moment.localeData('en');
var formatEn = getCustomLocalizedFormat('en');
var formatPt = getCustomLocalizedFormat('pt');

divEn.text(dateEn.format(formatEn));
divFi.text(dateFi.format(formatPt));
divRes.text(moment().format('MM/DD/YYYY h:mm:ss.SSS A'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.4/moment-with-locales.min.js"></script>

<p>English</p>
<div id="divEn"></div> 
<p>Portuguese</p>
<div id="divFi"></div>
<p>General</p>
<div id="divRes"></div>

Please note that:

  • This approach is not test for each locale supported by momentjs. Locales like pa-in(Punjabi), ml (Malayalam), ne (Nepalese), hi (Hindi), gom-latn (Konkani Latin script) and others have the LTS token that starts with A. It's not clear to me what is the your expected output for these locales.
  • You can customize Long Date Formats using updateLocale function and the longDateFormat key.

Probably the best approach is to define a subset of supported locales and define custom format for each locale (and/or just customized moment's LTS).

Upvotes: 5

Related Questions