【问题标题】:How do you format a Date/Time in TypeScript?如何在 TypeScript 中格式化日期/时间?
【发布时间】:2017-03-24 09:25:28
【问题描述】:

我在尝试在 TypeScript 中获取 Date 对象以按照我想要的方式格式化时遇到了一些麻烦。

我有一个类Module,定义为:

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);
    }
}

当我使用以下代码调用方法时:

    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());

我最终在控制台中打印了以下内容:

'9 November 2016 16:16:02 GMT'

我想看到的是:

09/11/2015 16:16

我查看了以下文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString,但我仍然看不出我做错了什么(我知道这是一个 JavaScript API 文档,但我很确定这就是 TypeScript 使用的引擎盖下)。

【问题讨论】:

  • 日期的格式不是 TypeScript 可以影响的,它只是 javascript。
  • @Alex 所以即使 TypeScript toLocale... 函数将接受一个语言环境和一个选项对象,它们本质上是无用的?
  • 没有这样的 TypeScript 函数,它是一个 javascript 函数。 TypeScript 只知道 api 并为其提供类型化接口。
  • 我现在明白了。看了一下转译的代码,它直接通过了原样。看起来问题出在 PhantomJS 及其实现日期 API 的方式上。从外观上看,它的日期格式与其他浏览器不同。在 Chrome 中运行它可以得到我期望的输出。

标签: javascript typescript


【解决方案1】:

更新(2022 年)

一个新的 js 日期 API 在第 3 阶段提案(时间 API)中。请看一下,您也许可以在不久的将来解决您的大部分问题:

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

更新(2020 年)

正如@jonhF 在 cmets 中指出的那样,MomentJs 建议不要再使用 MomentJs。 检查https://momentjs.com/docs/

相反,我将此列表与我个人的 TOP 3 js 日期库一起保存以供将来参考。

旧评论

(不要再使用momentjs lib,它已被弃用!!!)

我建议你使用MomentJS

通过 moment 你可以有很多输出,09/11/2015 16:16 就是其中之一。

【讨论】:

  • 2020 更新:Moment 现在建议不要使用 Moment。简短的解释是本机日期格式支持已经变得更好,如果您仍然需要更多,可以使用更小更好的库。查看他们的文档:momentjs.com/docs
【解决方案2】:

如果您想要超时以及想要的日期Date.toLocaleString()

这是直接来自我的控制台:

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

然后您可以输入语言环境字符串和格式字符串以获得您想要的精确输出。

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

【讨论】:

  • 我的控制台的输出是一样的。然而,当我在 TypeScript 中使用相同的代码时,我得到的结果与我原来的帖子相同。
  • 看起来问题出在 PhantomJS 及其实现日期 API 的方式上。从外观上看,它的日期格式与其他浏览器不同。在 Chrome 中运行它可以得到我期望的输出。
  • 不要让我开始使用 Phantom!原则上很棒,只是在愤怒时使用它时总是有类似的有趣错误!
【解决方案3】:
  1. 您可以创建继承自 PipeTransform 基础的管道
  2. 然后实现变换方法

在 Angular 4 中使用 - 它正在工作。格式化日期的最佳方式是管道。

像这样创建您的自定义管道:

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");
    }
  }

它在 TypeScript 类中使用,如下所示:

////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 
  }
}

【讨论】:

  • 对于 Angular,请勿在打字稿中使用 DatePipe。相反,您可以简单地使用formatDate 代替此处提到的stackoverflow.com/a/63902395/626639
  • @Seega 你能解释一下为什么不应该这样做吗?
  • 嗨@KLiFF,它不是破坏者,但管道的目的是在模板中使用。所以它更像是一个干净的代码。使用格式日期也可以使注入令牌的测试更清晰。
【解决方案4】:

还有一个要添加@kamalakar 的答案,需要在 app.module 中导入相同的内容并将 DateFormatPipe 添加到提供程序。

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

【讨论】:

    【解决方案5】:

    这是 Angular 的另一个选项(使用自己的格式化函数) - 这个选项用于格式化:

    YYYY-mm-dd hh:nn:ss

    -您可以调整格式,只需重新排列行并更改分隔符

    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);
    }
    

    对于当前时间戳使用如下:

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

    将输出例如:2018-12-31 23:00:01

    【讨论】:

      【解决方案6】:
      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') : '';
      }
      

      【讨论】:

        【解决方案7】:

        这对我有用

            /**
             * 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
            }
        

        你当然可以添加类似这样的 HH:MM...

            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
            }
        

        【讨论】:

          【解决方案8】:

          对我来说最好的解决方案是来自@Kamalakar 的自定义管道,但稍作修改以允许传递格式:

          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);
              }
            }
          

          然后调用为:

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

          【讨论】:

            【解决方案9】:

            选项 1: Momentjs:

            安装:

            npm install moment --save
            

            进口:

            import * as moment from 'moment';
            

            用法:

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

            选项 2: 如果您正在使用 Angular,请使用 DatePipe:

            进口:

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

            用法:

            const datepipe: DatePipe = new DatePipe('en-US')
            let formattedDate = datepipe.transform(yourDate, 'dd-MMM-YYYY HH:mm:ss')
            

            【讨论】:

            • 我认为的最佳答案。我不知道我们可以在组件中使用 DatePipe。谢谢兄弟
            • Moment.js 是一个遗留项目,现在处于维护模式。可能应该使用其他东西?
            • 对于 Angular,您应该使用 DatePipe。请查看我的回答stackoverflow.com/a/63902395/626639
            • 对于第二个选项,使用“dd-..”而不是“DD”
            【解决方案10】:

            对于 Angular,您应该简单地使用 formatDate 而不是 DatePipe

            import {formatDate} from '@angular/common';
            
            constructor(@Inject(LOCALE_ID) private locale: string) { 
                this.dateString = formatDate(Date.now(),'yyyy-MM-dd',this.locale);
            }
            

            【讨论】:

            • 这对我来说非常有用,除了我已经使用的之外,我不需要使用任何额外的导入。 formatDate 具有很好的灵活性,因为您可以传入日期或字符串或数字。此外,如果您不想注入 LACALE_ID 并使用 this.locale,您可以使用简单的字符串,例如 'en_US'
            【解决方案11】:

            如果您需要 Angular,使用最少代码的最简单方法是:

            import {formatDate} from '@angular/common';
            
            formatDate(Date.now(),'yyyy-MM-dd','en-US');
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-03-15
              • 2019-01-05
              • 2021-09-24
              • 1970-01-01
              • 2013-12-12
              相关资源
              最近更新 更多