Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you format a datetime to am/pm, without periods, when using date-fns version 2.x?

Version 2.x of the excellent date package date-fns only has these built-in am/pm formats.

date-fns am pm formats

How can I format the lower case am/pm without the periods?

like image 960
GollyJer Avatar asked Mar 17 '20 18:03

GollyJer


People also ask

Does date-fns support timezone?

Date-fns supports time zone data to work with UTC or ISO date strings. This will help you display the date and time in the local time of your users. The difficulty comes when working with another time zone's local time, for example showing the local time of an event in LA at 8 pm PST on a Node.

How do I use date-fns in browser?

In index. js we want to import the format function, which we can then pass today's date and a format string. We then want to output the result to the page. import { format } from 'date-fns'; const today = new Date(); const formattedDate = format(today, 'dd.


2 Answers

-- For datefns versions older than 2.23.0 --

Quick solution

Use aaaaa'm':

format(new Date(), "YYYY-MM-DD hh:mm aaaaa'm'")

Explanation: @GollyJer found a really clever way to work around this limitation. We can use aaaaa to yield a (for AM) or p (for PM) according to the documentation. Then we just follow it with the escaped character m, which is 'm', resulting in am or pm.

Note: this may result in a wrong output if you allow any kind of locale switching, because AM and PM may be different depending on the language.

Other ways

Nonetheless, for these versions, there's no native¹ way of doing this, as per documentation and source code reviewing, because the formatting is dependent on the locale configuration as shown in the source code (_lib/format/formatters/index.js):

// AM or PM
a: function(date, token, localize) {
  var hours = date.getUTCHours()
  var dayPeriodEnumValue = hours / 12 >= 1 ? 'pm' : 'am'

  switch (token) {
    case 'a':
    case 'aa':
    case 'aaa':
      return localize.dayPeriod(dayPeriodEnumValue, {
        width: 'abbreviated',
        context: 'formatting'
  })
  // ...

1: by native, I mean a straightforward native API formatter.

You can add a new locale to customize the strings though. This would imply changing this specific part (based on locale/en-US/_lib/localize/index.js):

var formattingDayPeriodValues = {
    // ...
    abbreviated: {
        am: 'AM',
        pm: 'PM',
        // ...
    }
    // ...
}

It's sad this new version doesn't have a straightforward way of customizing the default locales, or even just a simple way to apply a monkey-patch. Creating a new locale isn't elegant at all and replacing a.m. with am manually after the call to format isn't either.

Versions 1.x.x and 2.0.0 (alpha/beta)

For these versions, just use the a format. Example:

console.log(dateFns.format(new Date(), 'YYYY-MM-DD hh:mm a'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.30.1/date_fns.min.js"></script>
<!-- or: https://cdnjs.cloudflare.com/ajax/libs/date-fns/2.0.0-alpha0/date_fns.min.js -->

You can check for yourself in the source code the way it works:

var meridiemLowercase = [
    'am',
    'pm'
];

var formatters = {
    // ...
    'a': function (date) {
        return date.getHours() / 12 >= 1 ? meridiemLowercase[1] : meridiemLowercase[0];
    },
    // ...
}
like image 122
Toribio Avatar answered Oct 18 '22 04:10

Toribio


You can now use the aaa pattern for that case (v.2.23.0).

enter image description here

Source: https://date-fns.org/v2.23.0/docs/format

like image 39
Brunno Vodola Martins Avatar answered Oct 18 '22 05:10

Brunno Vodola Martins