107

I need to change a date/time from 2014-08-20 15:30:00 to look like 08/20/2014 3:30 pm

Can this be done using javascript's Date object?

user2994560
  • 1,269
  • 4
  • 18
  • 30
  • 2
    `Date()` should parse that. Assign that to a variable and then use the methods available to you to construct the format you want. They're [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date). – vch Aug 12 '14 at 23:29
  • It is better to use Intl.DateTimeFormat in Javascript and set an option for that. it is simple and more flexible. please see my post for more details. [link](https://stackoverflow.com/a/46725318/7487135). and online solution for your answer: [online answer](https://jsbin.com/regofipexa/2/edit?js,console) – Iman Bahrampour Oct 13 '17 at 08:23

5 Answers5

149

Yes, you can use the native javascript Date() object and its methods.

For instance you can create a function like:

function formatDate(date) {
  var hours = date.getHours();
  var minutes = date.getMinutes();
  var ampm = hours >= 12 ? 'pm' : 'am';
  hours = hours % 12;
  hours = hours ? hours : 12; // the hour '0' should be '12'
  minutes = minutes < 10 ? '0'+minutes : minutes;
  var strTime = hours + ':' + minutes + ' ' + ampm;
  return (date.getMonth()+1) + "/" + date.getDate() + "/" + date.getFullYear() + "  " + strTime;
}

var d = new Date();
var e = formatDate(d);

alert(e);

And display also the am / pm and the correct time.

Remember to use getFullYear() method and not getYear() because it has been deprecated.

DEMO http://jsfiddle.net/a_incarnati/kqo10jLb/4/

Ε Г И І И О
  • 11,199
  • 1
  • 48
  • 63
Alessandro Incarnati
  • 7,018
  • 3
  • 38
  • 54
  • 2
    I'm the first that use moment.js but in this case the question is very clear: Javascript format date / time. I answered to this a while back, in 2012 and I believe that It's always good to be able to use native js methods. Nowadays these libraries, like moment.js are even better, so it's really up to the developer if to use a library or rely purely on the language. – Alessandro Incarnati Oct 22 '15 at 06:45
  • Well, the answer is technically correct. Also, the question asked how Date object could be used for this, so technically, that's probably the most accurate answer to the question, if taken literally. However, such answer gives many programmers the feeling, that copying&pasting this snippet of code is what they should do, when facing such problem. That's IMO wrong. – Tomas Kulich Oct 23 '15 at 14:03
  • 2
    The month went wrong to me. Just worked fine when i used (), like (date.getMonth()+1). – Tiago Gouvêa Jul 23 '16 at 15:16
  • Why not put "new Date();" into the function, and then just formatDate(somestring)? Then you have one object constructor instead of fifty. – HoldOffHunger Mar 05 '18 at 22:30
89

Please do not reinvent the wheel. There are many open-source and COTS solutions that already exist to solve this problem.

Recommended

The following libraries are recommended for new projects.

Luxon (timezones, successor to Moment)

Luxon is the successor to the Moment.js library. It has native time zone and Intl support.

const { DateTime } = luxon;

const value = DateTime
  .fromFormat("2014-08-20 15:30:00", "yyyy-MM-dd HH:mm:ss")
  .toFormat('MM/dd/yyyy h:mm a');

console.log(value); // 08/20/2014 3:30 PM
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/3.3.0/luxon.min.js"></script>

js-joda (fixes the Date object)

This is a port of the Joda-Time library in Java. Joda-Time became the java.time package in the Java JDK in version 1.8. It is the successor to the Date object and improves it significantly.

const { DateTimeFormat, DateTimeFormatter, LocalDateTime } = JSJoda;
const { Locale } = JSJodaLocale;

const value = LocalDateTime
  .parse('2014-08-20 15:30:00',
    DateTimeFormatter.ofPattern('yyyy-M-d HH:mm:ss'))
  .format(DateTimeFormatter.ofPattern('MM/dd/yyyy h:mm a')
    .withLocale(Locale.US));
  
console.log(value); // 08/20/2014 3:30 PM
<script src="https://cdn.jsdelivr.net/npm/js-joda@1.11.0/dist/js-joda.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@js-joda/locale_en@4.8.10/dist/index.min.js"></script>

date-fns (fast, tree-shaking, server-side)

This is version 1.x, if you are using Node.js or another server-side JavaScript engine, you should use version 2.x.

const value = dateFns.format(
  dateFns.parse("2014-08-20 15:30:00", "yyyy-MM-dd HH:mm:ss"),
  'MM/DD/YYYY h:mm a');

console.log(value); // 08/20/2014 3:30 pm
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.30.1/date_fns.min.js"></script>

Day.js (smallest footprint)

A minimalist date library with plugins.

const value = dayjs("2014-08-20 15:30:00", "yyyy-MM-dd HH:mm:ss")
  .format('MM/DD/YYYY h:mm a');

console.log(value); // 08/20/2014 3:30 pm
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.7/dayjs.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.7/plugin/customParseFormat.min.js"></script>

date-and-time (small footprint)

A minimalist date library with plugins.

const value = date.format(
  date.parse("2014-08-20 15:30:00", "YYYY-MM-DD HH:mm:ss"),
  'MM/DD/YYYY h:mm A');

console.log(value); // 08/20/2014 3:30 PM
<script src="https://cdn.jsdelivr.net/npm/date-and-time@3.0.0/date-and-time.min.js"></script>

Not recommended

The following libraries are not recommended for new projects, because they are either no longer supported or do not follow best practices.

Moment (timezones, legacy)

Here is the original version using Moment. Since Luxon is the successor to Moment, I have included this as an alternative.

const value = moment('2014-08-20 15:30:00').format('MM/DD/YYYY h:mm a');

console.log(value); // 08/20/2014 3:30 pm
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>

Date.js (small footprint, archived)

This library manipulates the Date prototype. This is not considered best practice.

const value = Date.parse('2014-08-20 15:30:00').toString('MM/dd/yyyy hh:mm tt');

console.log(value); // 08/20/2014 03:30 PM
<script src="https://cdnjs.cloudflare.com/ajax/libs/datejs/1.0/date.min.js"></script>

Without a library

Now, if you really don't want to use a library, a simple tokenizer can assist you in parsing and formatting.

const TOKENS = new Set(['Y', 'M', 'D', 'H', 'h', 'm', 's', 'a']);

const main = () => {
  const value = format(parse('2014-08-20 15:30:00', 'YYYY-MM-DD HH:mm:ss'), 'MM/DD/YYYY h:mm a');
  console.log(value); // 08/20/2014 3:30 pm
};

const parse = (input, pattern) =>
  (tokens => new Date(
    +tokens['Y'] , +tokens['M'] - 1 , +tokens['D'],
    +tokens['H'] , +tokens['m']     , +tokens['s']
  ))(tokenize(input, pattern));

const format = (date, pattern) =>
  pattern.replace(/\b(\w)(\1)*\b/g, (match) => {
    switch (match[0]) {
      case 'Y': return date.getFullYear();
      case 'M': return `${date.getMonth() + 1}`.padStart(match.length, '0');
      case 'D': return `${date.getDate()}`.padStart(match.length, '0');
      case 'h': return `${date.getHours() % 12}`.padStart(match.length, '0');
      case 'm': return `${date.getMinutes()}`.padStart(match.length, '0');
      case 'a': return date.getHours() < 12 ? 'am' : 'pm';
    }
    return capture;
  });

const tokenize = (input, pattern) => 
  pattern.split('').reduce((acc, token, index) => TOKENS.has(token)
    ? { ...acc, [token]: (acc[token] ?? '') + input[index] }
    : acc, {});

main();
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
  • Had to convert a JSON array to work with a scheduler widget. This solution allowed me to nail it in under 5 minutes. Bravo. – Krafty Apr 26 '15 at 23:44
  • 69
    Wow, 12k just to format a date/time? There are times when reinventing the wheel makes perfect sense. If you are doing a lot of date manipulation then a library is the correct approach. If you need a one off solution with a smaller footprint then you could try http://stackoverflow.com/q/6312993/132599. – David Clarke Oct 26 '15 at 20:46
  • 4
    Sometimes a library is not an option (for example when using javascript on a couchdb database on a Cloudant server). – mtnpaul Jan 09 '16 at 08:47
  • 3
    "reinventing the wheel" - more like putting on a new tire, maybe a snow tire for more efficient traction! moments.js is like insisting on using 4 wheel drive on dry pavement.... – user2677034 Mar 01 '17 at 21:34
  • 2
    Plain Javascript actually is the wheel, and if people didn't try to reinvent it, great things like Moment.js wouldn't be around. – Dan Chase Oct 15 '18 at 18:21
  • @DanChase It's more of a proverb in this context. Essentially, let the engineers engineer things so that the designers can design things and the data-scientist can do analysis. – Mr. Polywhirl Oct 17 '18 at 15:04
19

For the date part:(month is 0-indexed while days are 1-indexed)

var date = new Date('2014-8-20');
console.log((date.getMonth()+1) + '/' + date.getDate() + '/' +  date.getFullYear());

for the time you'll want to create a function to test different situations and convert.

Neeraj Kumar
  • 771
  • 2
  • 16
  • 37
Bray
  • 361
  • 1
  • 10
  • 1
    why is it indexed differently? – almost a beginner Apr 26 '17 at 04:59
  • Maybe because they have two different interpretations: days of month have by nature a numbering and they are only characterized by this number. In this case this is not an index, while months are often characterized by their name. That's why it's an indexed representation (and that's why they start at 0). It's still painful to use. – Glandalf Jan 25 '20 at 10:41
14

I don't think that can be done RELIABLY with built in methods on the native Date object. The toLocaleString method gets close, but if I am remembering correctly, it won't work correctly in IE < 10. If you are able to use a library for this task, MomentJS is a really amazing library; and it makes working with dates and times easy. Otherwise, I think you will have to write a basic function to give you the format that you are after.

function formatDate(date) {
    var year = date.getFullYear(),
        month = date.getMonth() + 1, // months are zero indexed
        day = date.getDate(),
        hour = date.getHours(),
        minute = date.getMinutes(),
        second = date.getSeconds(),
        hourFormatted = hour % 12 || 12, // hour returned in 24 hour format
        minuteFormatted = minute < 10 ? "0" + minute : minute,
        morning = hour < 12 ? "am" : "pm";

    return month + "/" + day + "/" + year + " " + hourFormatted + ":" +
            minuteFormatted + morning;
}
boatcoder
  • 17,525
  • 18
  • 114
  • 178
Christopher
  • 404
  • 2
  • 9
2

You can do that:

function formatAMPM(date) { // This is to display 12 hour format like you asked
  var hours = date.getHours();
  var minutes = date.getMinutes();
  var ampm = hours >= 12 ? 'pm' : 'am';
  hours = hours % 12;
  hours = hours ? hours : 12; // the hour '0' should be '12'
  minutes = minutes < 10 ? '0'+minutes : minutes;
  var strTime = hours + ':' + minutes + ' ' + ampm;
  return strTime;
}

var myDate = new Date();
var displayDate = myDate.getMonth()+ '/' +myDate.getDate()+ '/' +myDate.getFullYear()+ ' ' +formatAMPM(myDate);
console.log(displayDate);

Fiddle

Nick Rameau
  • 1,258
  • 14
  • 23