167

I've been having some trouble trying to get a Date object in TypeScript to format the way I want it to.

I have a class Module which is defined as:

export class Module {

    constructor(public id: number, public name: string, public description: string, 
                 public lastUpdated: Date, public owner: string) { }

    getNiceLastUpdatedTime(): String {

        let options: Intl.DateTimeFormatOptions = {
            day: "numeric", month: "numeric", year: "numeric",
            hour: "2-digit", minute: "2-digit"
        };

        return this.lastUpdated.toLocaleDateString("en-GB", options) + " " + this.lastUpdated.toLocaleTimeString("en-GB", options);
    }
}

When I call the method with the following code:

    let date = new Date(1478708162000); // 09/11/2016 16:16pm (GMT)
    let module = new Module(1, "Test", "description", date, "test owner");
    console.log(module.getNiceLastUpdatedTime());

I end up with the following printed in the console:

'9 November 2016 16:16:02 GMT'

What I want to see is:

09/11/2015 16:16

I've had a look at the documentation at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString and I still can't see what I'm doing wrong (I know this is a JavaScript API documentation but I'm pretty sure that's what TypeScript is using under the hood).

4
  • 1
    The formatting of a Date is not something TypeScript has influence over, that's just javascript.
    – Alex
    Commented Nov 10, 2016 at 11:21
  • @Alex so even though the TypeScript toLocale... functions will accept a locale and an options object they're essentially useless? Commented Nov 10, 2016 at 13:41
  • 1
    There is no TypeScript function like that, that is a javascript function. TypeScript merely knows the api and provides a typed interface for it.
    – Alex
    Commented Nov 10, 2016 at 13:47
  • I get you now. Had a look at the transpiled code and it just passes it straight through untouched. It looks like the problem was with PhantomJS and the way it implements the Date API. It formats dates differently from the other browsers by the looks of it. Running it in Chrome gives me the output I expect. Commented Nov 10, 2016 at 13:47

14 Answers 14

141

If you want the time out as well as the date you want Date.toLocaleString().

This was direct from my console:

> new Date().toLocaleString()
> "11/10/2016, 11:49:36 AM"

You can then input locale strings and format string to get the precise output you want.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString

2
  • 3
    The output from my console is the same. When I use the same code in TypeScript however, I get the same result as my original post. Commented Nov 10, 2016 at 13:39
  • It looks like the problem was with PhantomJS and the way it implements the Date API. It formats dates differently from the other browsers by the looks of it. Running it in Chrome gives me the output I expect. Commented Nov 10, 2016 at 13:49
62

Option 1: Momentjs:

Install:

npm install moment --save

Import:

import * as moment from 'moment';

Usage:

let formattedDate = (moment(yourDate)).format('DD-MMM-YYYY HH:mm:ss')

Option 2: Use DatePipe if you are doing Angular:

Import:

import { DatePipe } from '@angular/common';

Usage:

const datepipe: DatePipe = new DatePipe('en-US')
let formattedDate = datepipe.transform(yourDate, 'dd-MMM-YYYY HH:mm:ss')
4
  • 11
    Moment.js is a legacy project, now in maintenance mode. probably should use something else 👌 Commented Oct 11, 2020 at 14:30
  • 2
    For Angular you should NOT use the DatePipe. Please checkout my answer stackoverflow.com/a/63902395/626639
    – Seega
    Commented Mar 8, 2021 at 13:23
  • 2
    For the second option, use "dd-.." instead of "DD"
    – Smaillns
    Commented Apr 2, 2021 at 10:40
  • The import statement should be import moment from 'moment'
    – RMRiver
    Commented Aug 23, 2022 at 10:30
49

For Angular you should simply use formatDate instead of the DatePipe.

import {formatDate} from '@angular/common';

constructor(@Inject(LOCALE_ID) private locale: string) { 
    this.dateString = formatDate(Date.now(),'yyyy-MM-dd',this.locale);
}
1
  • 3
    This worked great for me, I didn't have to use any additional imports aside from what I was already using. formatDate has a good flexibility because you can pass in a date or a string or a number. Also if you don't want to inject LACALE_ID and use this.locale you can use a simple string like 'en_US' Commented Jul 30, 2021 at 22:15
36

Using the The Temporal API (2023)

A new js date api is in Stage 3 proposal (The Temporal API). Please take a look at that, you might be able to resolve most of your problems in a near future with it:

https://tc39.es/proposal-temporal/docs/index.html

Stop using momentjs - see alternatives below

As pointed by @jonhF in the comments, MomentJs recommends to not use MomentJs anymore. Check https://momentjs.com/docs/

Instead, I'm keeping this list with my personal TOP 3 js date libraries for future reference.

Old comment

(Don't use momentjs lib anymore, it is deprecated!!!)

I suggest you to use MomentJS

With moment you can have lot of outputs, and this one 09/11/2015 16:16 is one of them.

2
  • 3
    2020 update: Moment is now suggesting to not use Moment. The short explanation is that native date formatting support has gotten better and if you still need more there are smaller and better libraries available. See their Docs: momentjs.com/docs
    – JohnF
    Commented Oct 30, 2020 at 7:15
  • upvote for "stop using moment.js" :) Commented Sep 1, 2023 at 8:30
20

In case you need it for angular, the simplest aproach with minimum code is:

import {formatDate} from '@angular/common';

formatDate(Date.now(),'yyyy-MM-dd','en-US');
17
  1. You can create pipe inherited from PipeTransform base
  2. Then implement transform method

Used in Angular 4 - it's working. Best way to format a date is a pipe.

Create your custom pipe like this:

import { Pipe, PipeTransform} from '@angular/core';
import { DatePipe } from '@angular/common';

@Pipe({
    name: 'dateFormat'
  })
  export class DateFormatPipe extends DatePipe implements PipeTransform {
    transform(value: any, args?: any): any {
       ///MMM/dd/yyyy 
       return super.transform(value, "MMM/dd/yyyy");
    }
  }

and it's used in a TypeScript class like this:

////my class////

export class MyComponent
{
  constructor(private _dateFormatPipe:DateFormatPipe)
  {
  }

  formatHereDate()
  {
     let myDate = this._dateFormatPipe.transform(new Date())//formatting current ///date here 
     //you can pass any date type variable 
  }
}
3
  • 1
    For Angular do not use the DatePipe in the typescript. Instead, you can simply use formatDate instead as mentioned here stackoverflow.com/a/63902395/626639.
    – Seega
    Commented Aug 12, 2021 at 14:46
  • @Seega Could you please explain why this should not be done this way?
    – KLiFF
    Commented Aug 31, 2021 at 13:59
  • Hi @KLiFF, it is not a dealbreaker but the purpose of a pipe is to be used in a template. So it is more a clean-code thing. Also using format date is making testing cleaner with the injection token.
    – Seega
    Commented Sep 3, 2021 at 12:00
13

Here is another option for Angular (using own formatting function) - this one is for format:

YYYY-mm-dd hh:nn:ss

-you can adjust to your formats, just re-order the lines and change separators

dateAsYYYYMMDDHHNNSS(date): string {
  return date.getFullYear()
            + '-' + this.leftpad(date.getMonth() + 1, 2)
            + '-' + this.leftpad(date.getDate(), 2)
            + ' ' + this.leftpad(date.getHours(), 2)
            + ':' + this.leftpad(date.getMinutes(), 2)
            + ':' + this.leftpad(date.getSeconds(), 2);
}

leftpad(val, resultLength = 2, leftpadChar = '0'): string {
  return (String(leftpadChar).repeat(resultLength)
        + String(val)).slice(String(val).length);
}

For current time stamp use like this:

const curTime = this.dateAsYYYYMMDDHHNNSS(new Date());
console.log(curTime);

Will output e.g: 2018-12-31 23:00:01

5
function _formatDatetime(date: Date, format: string) {
   const _padStart = (value: number): string => value.toString().padStart(2, '0');
return format
    .replace(/yyyy/g, _padStart(date.getFullYear()))
    .replace(/dd/g, _padStart(date.getDate()))
    .replace(/mm/g, _padStart(date.getMonth() + 1))
    .replace(/hh/g, _padStart(date.getHours()))
    .replace(/ii/g, _padStart(date.getMinutes()))
    .replace(/ss/g, _padStart(date.getSeconds()));
}
function isValidDate(d: Date): boolean {
    return !isNaN(d.getTime());
}
export function formatDate(date: any): string {
    var datetime = new Date(date);
    return isValidDate(datetime) ? _formatDatetime(datetime, 'yyyy-mm-dd hh:ii:ss') : '';
}
0
1

1º Install: npm install moment --save 2º Make Import : import moment, { Moment } from 'moment' 3º Coder:

var date = Date.now()
let formattedDate = (moment(date)).format('YYYY-MM-DD HH:mm:ss')
0

One more to add @kamalakar's answer, need to import the same in app.module and add DateFormatPipe to providers.

    import {DateFormatPipe} from './DateFormatPipe';
    @NgModule
    ({ declarations: [],  
        imports: [],
        providers: [DateFormatPipe]
    })
0

You can use

function formatDate(date) { 
 return date.toISOString().replace('T', ' ').replaceAll('-', '/').substring(0, 19);
}

const currentdate = new Date();

console.log(formatDate(currentdate));

-2

This worked for me

    /**
     * Convert Date type to "YYYY/MM/DD" string 
     * - AKA ISO format?
     * - It's logical and sortable :)
     * - 20200227
     * @param Date eg. new Date()
     * https://stackoverflow.com/questions/23593052/format-javascript-date-as-yyyy-mm-dd 
     * https://stackoverflow.com/questions/23593052/format-javascript-date-as-yyyy-mm-dd?page=2&tab=active#tab-top
     */
    static DateToYYYYMMDD(Date: Date): string {
        let DS: string = Date.getFullYear()
            + '/' + ('0' + (Date.getMonth() + 1)).slice(-2)
            + '/' + ('0' + Date.getDate()).slice(-2)
        return DS
    }

You can certainly add HH:MM something like this...

    static DateToYYYYMMDD_HHMM(Date: Date): string {
        let DS: string = Date.getFullYear()
            + '/' + ('0' + (Date.getMonth() + 1)).slice(-2)
            + '/' + ('0' + Date.getDate()).slice(-2)
            + ' ' + ('0' + Date.getHours()).slice(-2)
            + ':' + ('0' + Date.getMinutes()).slice(-2)
        return DS
    }
-2

The best solution for me is the custom pipe from @Kamalakar but with a slight modification to allow passing the format:

import { Pipe, PipeTransform} from '@angular/core';
import { DatePipe } from '@angular/common';

@Pipe({
    name: 'dateFormat'
  })
  export class DateFormatPipe extends DatePipe implements PipeTransform {
    transform(value: any, format: any): any {
       return super.transform(value, format);
    }
  }

And then called as:

console.log('Formatted date:', this._dateFormatPipe.transform(new Date(), 'MMM/dd/yyyy'));
-3

Here is an Example of a simple date format function

formatDate(value, format, offset){
 format = format || 'yyyy-MM-dd';
 offset = offset || '+0300';

if(!(value instanceof Date)){
   value = new Date(value);
   if(value === null || value === undefined) {
      throw new Error(
      'DateFormatException: value passed' + 'is not a valid date'
      );
    }
  }
  return value; // TODO implement this return $filter('date')(value, format, offset);
}
2
  • your function is missing a meaningful body Commented Mar 21, 2023 at 16:35
  • looks not clean bro, hard to read my gangsta
    – IonicMan
    Commented Apr 11, 2023 at 11:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.