ChatGPT解决这个技术问题 Extra ChatGPT

将 JavaScript 日期格式化为 yyyy-mm-dd

我有一个格式为 Sun May 11,2014 的日期。如何使用 JavaScript 将其转换为 2014-05-11

函数 taskDate(dateMilli) { var d = (new Date(dateMilli) + '').split(' '); d[2] = d[2] + ',';返回 [d[0], d[1], d[2], d[3]].join(' '); } var datemilli = Date.parse('Sun May 11,2014'); console.log(taskDate(datemilli));

上面的代码给了我相同的日期格式,sun may 11,2014。我怎样才能解决这个问题?

真正考虑使用像 Moment.js 这样的库。它将格式化为所需的结果:)
当 5 行代码可以完成工作时,为什么要使用库? @Ankur
相关:What are valid Date Time Strings in JavaScript? 请注意,“Sun May 11,2014”不是有效的日期字符串,在某些浏览器中解析它可能会失败。
@Black Mamba 为什么在几行骗局时使用库

L
Lindauson

只需利用将日期转换为 ISO 8601 格式的内置 toISOString 方法:

let yourDate = new Date()
yourDate.toISOString().split('T')[0]

yourDate 是您的日期对象。

编辑@exbuddha 编写此代码是为了处理 comments 中的时区:

const offset = yourDate.getTimezoneOffset()
yourDate = new Date(yourDate.getTime() - (offset*60*1000))
return yourDate.toISOString().split('T')[0]

请小心使用此方法,因为它首先将日期转换为 UTC。如果您在 + 时区并且您的时间部分是在一天的早些时候,那么它可能会回滚一天。或者,如果您在 - 时区并且您的时间部分在当天晚些时候,那么它可以向前滚动一天。
试试这个:new Date(yourDateStr).toISOString().split('T')[0]
const offset = yourDate.getTimezoneOffset(); yourDate = new Date(yourDate.getTime() + (offset*60*1000)); yourDate.toISOString().split('T')[0] 这应该可以解决时区问题
now.toISOString().substring(0,10); 这是一个更简洁的替代方案,因为它提醒您 YYYY-MM-DD 是完整 iso 格式的前十个字符
注意:使用@mjwrazor 评论的有用解决方案,我必须减去而不是添加偏移量才能获得正确的日期(将 + (offset 更改为 - (offset
K
Kos

你可以做:

function formatDate(date) { var d = new Date(date), month = '' + (d.getMonth() + 1), day = '' + d.getDate(), year = d.getFullYear(); if (month.length < 2) 月 = '0' + 月; if (day.length < 2) day = '0' + day; return [年、月、日].join('-'); } console.log(formatDate('Sun May 11,2014'));

使用示例:

console.log(formatDate('Sun May 11,2014'));

输出:

2014-05-11

JSFiddle 上的演示:http://jsfiddle.net/abdulrauf6182012/2Frm3/


在同一个语句中真的有多个变量声明吗? stackoverflow.com/questions/694102/…
@Fuser97381 同一语句中的多个变量声明不仅仅是一种审美风格偏好。这是一种危险的做法。如果您无意中失败,则在每个声明后添加一个逗号,您最终会创建全局变量。不应该鼓励什么可能成为问题的规范答案。
'use strict';@bhspencer
重新格式化日期字符串不应依赖于内置解析器对非标准字符串的成功解析。给定 OP 格式,它可以用更少的代码重新格式化,而无需使用 Date。
这就像一个魅力,但我不明白为什么 javascript 没有为此提供本机解决方案......我的意思是,我们在 2020 年,日期是网络应用程序的一个重要方面。
R
Ruslan López

我使用这种方式以 yyyy-mm-dd 格式获取日期 :)

var todayDate = new Date().toISOString().slice(0, 10);控制台.log(今天日期);


正如@Luke_Baulch 在这里提到的,你如何处理一天的日期切换?
你可以这样做: var todayDate = new Date(); todayDate.setMinutes(todayDate.getMinutes() - todayDate.getTimezoneOffset()); todayDate.toISOString().slice(0,10);这应该有助于避免 UTC 问题。
@FernandoAguilar 不过有一个疑问,我们怎么知道我们需要减去或添加偏移量?
var todayDate = new Date(2018, 3 - 1, 26); todayDate.toISOString().slice(0, 10); 给了我"2018-03-25"。在另一个系统上 var todayDate = new Date(2018, 3 - 1, 26, 17, 0, 0); todayDate.toISOString().slice(0, 10); 给了我 "2018-03-27"
并不总是有效。由于 UTC 转换,它有时会减去一天。
C
Carson

2020年答案

您可以使用原生 .toLocaleDateString() 函数,该函数支持多个有用的参数,例如 locale(选择 MM/DD/YYYY 或 YYYY/MM/DD 等格式)、timezone (转换日期)和格式详细信息options(例如:1 vs 01 vs January)。

例子

const testCases = [ new Date().toLocaleDateString(), // 8/19/2020 new Date().toLocaleString(undefined, {year: 'numeric', month: '2-digit', day: '2-digit ', weekday:"long", hour: '2-digit', hour12: false, minute:'2-digit', second:'2-digit'}), new Date().toLocaleDateString('en-US' , {year: 'numeric', month: '2-digit', day: '2-digit'}), // 2020 年 8 月 19 日(带两位数的月份和日期) new Date().toLocaleDateString('en -ZA'), // 2020/08/19 (年/月/日) 注意不同的语言环境 new Date().toLocaleDateString('en-CA'), // 2020-08-19 (年-月-日) ) 注意不同的语言环境 new Date().toLocaleString("en-US", {timeZone: "America/New_York"}), // 8/19/2020, 9:29:51 AM。 (特定时区的日期和时间) new Date().toLocaleString("en-US", {hour: '2-digit', hour12: false, timeZone: "America/New_York"}), // 09 (just小时) ] for (const testData of testCases) { console.log(testData) }

请注意,有时要以您想要的特定格式输出日期,您必须找到与该格式兼容的语言环境。您可以在此处找到语言环境示例:https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_tolocalestring_date_all

请注意,语言环境只是更改格式,如果要将特定日期转换为特定国家或城市时间,则需要使用时区参数。


这仍然存在时区问题,因为它基于 UTC,因此您仍然必须跳过所有确定偏移量和更改日期的环节。
@TimHobbs 您可以设置所需的时区,例如: ("timeZone: "America/New_York") 并且日期将转换为该时区。
对于我不需要时区的情况,new Date().toLocaleDateString('en-CA') 是完美的
您可以在 toLocaleDateString() 中格式化为 yyyy/mm/dd 吗?
@JamesPoulose 是的,你可以做 new Date().toLocaleDateString('en-ZA');
J
John Slegers

将日期转换为 yyyy-mm-dd 格式的最简单方法是:

var date = new Date("Sun May 11,2014");
var dateString = new Date(date.getTime() - (date.getTimezoneOffset() * 60000 ))
                    .toISOString()
                    .split("T")[0];

这个怎么运作:

new Date("Sun May 11,2014") 将字符串“Sun May 11,2014”转换为日期对象,该对象表示基于当前语言环境(主机系统设置)的时区中的时间 Sun May 11 2014 00:00:00

new Date(date.getTime() - (date.getTimezoneOffset() * 60000 )) 通过减去时间,将您的日期转换为与 UTC(标准时间)中 Sun May 11 2014 00:00:00 的时间相对应的日期对象区域偏移

.toISOString() 将日期对象转换为 ISO 8601 字符串 2014-05-11T00:00:00.000Z

.split("T") 将字符串拆分为数组 ["2014-05-11", "00:00:00.000Z"]

[0] 获取该数组的第一个元素

演示

var date = new Date("2014 年 5 月 11 日星期日"); var dateString = new Date(date.getTime() - (date.getTimezoneOffset() * 60000 )) .toISOString() .split("T")[0];控制台.log(dateString);


没有其他人对这是最简单的方法感到震惊??
@JoeDevmon:我看不出这与这里有什么关系。 - (date.getTimezoneOffset() * 60000 ) 位应消除任何时区差异,包括夏令时的影响。
@JohnSlegers 这就是我的想法,但在某些情况下我仍然在前一天得到。我重构了,你的例子现在可以工作了。我一定有一个奇怪的日期字符串或其他东西。感谢您坚持并指出这一点。 +1 👍
我在 SO 和其他网站上进行了高低搜索,以找到处理 JS 中日期的时区问题的最佳方法,并且放下手,这是迄今为止最简单和最好的。谢谢!
可悲的是,这是将 js 日期格式化为您需要的字符串的最简单方法。我是 js 新手,但在 java 中,将日期格式化为任何格式要容易 100 倍。这就是为什么认为有更简单的方法,但在我尝试了不同的解决方案后,我选择了这个。谢谢您的回答。
a
aqwsez

一些答案的组合:

var d = new Date(date);
date = [
  d.getFullYear(),
  ('0' + (d.getMonth() + 1)).slice(-2),
  ('0' + d.getDate()).slice(-2)
].join('-');

我最喜欢这个解决方案 - 易于阅读,并且不依赖于 toISOString() 以及使用该函数时潜在的时区陷阱。
这是第一个不会让我的大脑受伤的。
如果日期字符串已采用预期的输出格式并且本地时区在 UTC 以西,则此操作在 Chrome 中失败:d = new Date('2022-05-18') 导致“2022-05-17”。这意味着如果用户的区域设置格式不是“5/18/2022”,这也可能会中断。
A
AJP
format = function date2str(x, y) {
    var z = {
        M: x.getMonth() + 1,
        d: x.getDate(),
        h: x.getHours(),
        m: x.getMinutes(),
        s: x.getSeconds()
    };
    y = y.replace(/(M+|d+|h+|m+|s+)/g, function(v) {
        return ((v.length > 1 ? "0" : "") + z[v.slice(-1)]).slice(-2)
    });

    return y.replace(/(y+)/g, function(v) {
        return x.getFullYear().toString().slice(-v.length)
    });
}

结果:

format(new Date('Sun May 11,2014'), 'yyyy-MM-dd')
"2014-05-11

我喜欢这个解决方案提供的额外灵活性,而不是这个问题的其他答案。我尚未对此进行彻底测试,但对于我想要的格式(即“yyyy-MM-dd hh:mm:ss”),它可以按预期工作。
您可以轻松避免 eval
这是一个更好地避免评估和评论的版本jsfiddle.net/8904cmLd/2
我从这个回应中受益。我确实将该行替换为 return ((v.length > 1 ? "0" : "") + z[v.slice(-1)]).slice(-2); 的 eval 语句
“H”应该大写,而不是“h”(小)
P
Peter Mortensen

如果您对使用库没有任何反对意见,则可以像这样使用 Moments.js 库:

var now = new Date(); var dateString = moment(now).format('YYYY-MM-DD'); var dateStringWithTime = moment(now).format('YYYY-MM-DD HH:mm:ss');


很酷的解决方案,但它是一个 300kb 的包
应用于 react 项目:npm install moment --save import moment from 'moment'; const showEventDate = moment(your-date-here).format('YYYY-MM-DD; HH:mm A'); 以任何格式呈现日期/时间的纯解决方案。它提供带有 AM/PM 的本地日期时间以及您只需要更改格式的任何内容。 Moment.js 还提供简单的日期/时间计数解决方案。
@theTradeCoder 正如 Adam 上面提到的那样,moment 的大小非常大(我认为它更像是 67kb,但仍然如此)所以在评估任何依赖项的易用性和实用性时应该考虑到这一点。还有更小的替代品(day.js = 2kb)。
只是关于 moment.js 库的更新 - moment.js 已经停产。
A
Aleksandr Belugin

您可以在 Date 对象上使用 toLocaleDateString('fr-CA')

console.log(new Date('Sun May 11,2014').toLocaleDateString('fr-CA'));

我还发现这些语言环境从这个语言环境列表中给出了正确的结果 List of All Locales and Their Short Codes?

'en-CA'
'fr-CA'
'lt-LT'
'sv-FI'
'sv-SE'

var localesList = [“af-ZA”、“am-ET”、“ar-AE”、“ar-BH”、“ar-DZ”、“ar-EG”、“ar-IQ”、“ar-JO ”、“ar-KW”、“ar-LB”、“ar-LY”、“ar-MA”、“arn-CL”、“ar-OM”、“ar-QA”、“ar-SA”、 “ar-SY”、“ar-TN”、“ar-YE”、“as-IN”、“az-Cyrl-AZ”、“az-Latn-AZ”、“ba-RU”、“be-BY” "、"bg-BG"、"bn-BD"、"bn-IN"、"bo-CN"、"br-FR"、"bs-Cyrl-BA"、"bs-Latn-BA"、"ca -ES”、“co-FR”、“cs-CZ”、“cy-GB”、“da-DK”、“de-AT”、“de-CH”、“de-DE”、“de-LI ”、“de-LU”、“dsb-DE”、“dv-MV”、“el-GR”、“en-029”、“en-AU”、“en-BZ”、“en-CA”、 “en-GB”、“en-IE”、“en-IN”、“en-JM”、“en-MY”、“en-NZ”、“en-PH”、“en-SG”、“en -TT”、“en-US”、“en-ZA”、“en-ZW”、“es-AR”、“es-BO”、“es-CL”、“es-CO”、“es-CR” "、"es-DO"、"es-EC"、"es-ES"、"es-GT"、"es-HN"、"es-MX"、"es-NI"、"es-PA"、 “es-PE”、“es-PR”、“es-PY”、“es-SV”、“es-US”、“es-UY”、“es-VE”、“et-EE”、“eu” -ES”、“fa-IR”、“fi-FI”、“fil-PH”、“fo-FO”、“fr-BE”、“fr-CA”、“fr-CH”、“fr-FR” ”、“fr-LU”、“fr-MC”、“fy-NL”、“ga-IE”、“gd-GB”、“gl-ES”、“gsw-FR”、“gu-IN”、 “ha-Latn-NG”、“he-IL”、“hi-IN”、“hr-BA”、“hr-HR”、“hsb-DE”、“hu-HU”、“hy-A” M”、“id-ID”、“ig-NG”、“ii-CN”、“is-IS”、“it-CH”、“it-IT”、“iu-Cans-CA”、“iu- Latn-CA”、“ja-JP”、“ka-GE”、“kk-KZ”、“kl-GL”、“km-KH”、“kn-IN”、“kok-IN”、“ko- KR”、“ky-KG”、“lb-LU”、“lo-LA”、“lt-LT”、“lv-LV”、“mi-NZ”、“mk-MK”、“ml-IN” , “mn-MN”, “mn-Mong-CN”, “moh-CA”, “mr-IN”, “ms-BN”, “ms-MY”, “mt-MT”, “nb-NO” 、“ne-NP”、“nl-BE”、“nl-NL”、“nn-NO”、“nso-ZA”、“oc-FR”、“or-IN”、“pa-IN”、“ pl-PL”、“prs-AF”、“ps-AF”、“pt-BR”、“pt-PT”、“qut-GT”、“quz-BO”、“quz-EC”、“quz- PE”、“rm-CH”、“ro-RO”、“ru-RU”、“rw-RW”、“sah-RU”、“sa-IN”、“se-FI”、“se-NO” 、“se-SE”、“si-LK”、“sk-SK”、“sl-SI”、“sma-NO”、“sma-SE”、“smj-NO”、“smj-SE”、“ smn-FI”、“sms-FI”、“sq-AL”、“sr-Cyrl-BA”、“sr-Cyrl-CS”、“sr-Cyrl-ME”、“sr-Cyrl-RS”、“ sr-Latn-BA”、“sr-Latn-CS”、“sr-Latn-ME”、“sr-Latn-RS”、“sv-FI”、“sv-SE”、“sw-KE”、“ syr-SY”、“ta-IN”、“te-IN”、“tg-Cyrl-TJ”、“th-TH”、“tk-TM”、“tn-ZA”、“tr-TR”、“ tt-RU”、“tzm-Latn-DZ”、“ug-CN”、“uk-UA”、“ur-PK”、“uz-Cyrl-UZ”、“uz-Latn-UZ”、“vi- VN”、“wo-SN”、“xh-ZA”、“yo-NG”、“zh-CN”、“zh-HK”、“zh- MO”、“zh-SG”、“zh-TW”、“zu-ZA”]; localesList.forEach(lcl => { if ("2014-05-11" === new Date('Sun May 11,2014').toLocaleDateString(lcl)) { console.log(lcl, new Date('Sun May 11,2014').toLocaleDateString(lcl)); } });


知道为什么会这样吗? ISO 格式只是默认格式,还是这些语言环境真正使用该格式?如果是前者,我担心它会在未来发生意想不到的变化。
这不适用于浏览器之外的 NodeJS。
@jymbob 我认为这些语言环境真正使用了这些格式。通过查看此 Wikipedia 页面,我得出了相同的答案:en.wikipedia.org/wiki/Date_format_by_country
3 天后,浏览了太多的 SO javascript 日期问题,并尝试在这里提出一个新问题(作为重复关闭前 30 分钟)终于是一个实际上是正确的答案。我可以哭泣。
感谢这些代码,这确实是在 js 渲染中获取格式的更好捷径。
P
Peter Mortensen

只需使用这个:

var date = new Date('1970-01-01'); // Or your date here
console.log((date.getMonth() + 1) + '/' + date.getDate() + '/' +  date.getFullYear());

简单而甜蜜;)


字母格式没有填充。如果日期或月份小于 10,它将显示单个数字,这就是为什么不能直接使用它的原因。
是的,但这可以简单地使用 javascript 来实现,我认为它完全符合您的要求,不是吗? @YatenderSingh
是的,但请检查他想要的问题“yyyy-mm-dd”格式的标题:)
var old_date = 新日期(日期); var new_date = old_date.getFullYear() + '-' + (old_date.getMonth() + 1) + '-' + old_date.getDate()
K
Kamil Kiełczewski

最短的

.toJSON().slice(0,10);

var d = new Date('Sun May 11,2014' +' UTC'); // 解析为 UTC let str = d.toJSON().slice(0,10); // 显示为 UTC console.log(str);


当客户端早于 UTC 并且 UTC 时间中的日期比当前客户端日期晚一天时,这不起作用。
如果您不在 00+00 时区,我们不需要屏幕截图:> d=new Date() ; d.setHours(0,30,0,0) ; d --> Sat Oct 09 2021 00:30:00 GMT+0100 (BST) ; d.toJSON() --> “2021-10-08T23:30:00.000Z”
P
Peter Mortensen

toISOString() 假定您的日期是当地时间并将其转换为 UTC。您将得到一个不正确的日期字符串。

以下方法应该返回您需要的内容。

Date.prototype.yyyymmdd = function() {         

    var yyyy = this.getFullYear().toString();                                    
    var mm = (this.getMonth()+1).toString(); // getMonth() is zero-based         
    var dd  = this.getDate().toString();             

    return yyyy + '-' + (mm[1]?mm:"0"+mm[0]) + '-' + (dd[1]?dd:"0"+dd[0]);
};

来源:https://blog.justin.kelly.org.au/simple-javascript-function-to-format-the-date-as-yyyy-mm-dd/


L
Luo Jiong Hui

检索年、月和日,然后将它们放在一起。直接、简单、准确。

函数 formatDate(date) { var year = date.getFullYear().toString(); var month = (date.getMonth() + 101).toString().substring(1); var day = (date.getDate() + 100).toString().substring(1);返回年+“-”+月+“-”+日; } //使用示例:alert(formatDate(new Date()));


这是正确的
H
Hendrik Jan

使用 Intl 的 2021 年解决方案。

所有浏览器现在都支持新的 Intl 对象。
您可以通过选择使用所需格式的“区域设置”来选择格式。

瑞典语语言环境使用格式“yyyy-mm-dd”:

// Create a date
const date = new Date(2021, 10, 28);

// Create a formatter using the "sv-SE" locale
const dateFormatter = Intl.DateTimeFormat('sv-SE');

// Use the formatter to format the date
console.log(dateFormatter.format(date)); // "2021-11-28"

使用 Intl 的缺点:

您不能使用此方法“取消格式化”或“解析”字符串

您必须搜索所需的格式(例如在维基百科上)并且不能使用像“yyyy-mm-dd”这样的格式字符串


L
Luca C.

在大多数情况下(无时区处理),这就足够了:

date.toISOString().substring(0,10)

例子

var date = new Date();
console.log(date.toISOString()); // 2022-07-04T07:14:08.925Z
console.log(date.toISOString().substring(0,10)); // 2022-07-04

注意“日期”应该是这一行之前的 var date = new Date()。或者,只是 new Date() .toISOString().substring(0,10);
P
Peter Mortensen

还要考虑时区,如果没有任何库,这个单行应该很好:

new Date().toLocaleString("en-IN", {timeZone: "Asia/Kolkata"}).split(',')[0]

问题是每个语言环境都会返回不同的结果。例如,en-GB 将返回 20/12/2012,而 ko-KR 将返回2012. 12. 20.。但格式应为 yyyy-mm-dd
P
Peter Mortensen

你可以试试这个:https://www.npmjs.com/package/timesolver

npm i timesolver

在您的代码中使用它:

const timeSolver = require('timeSolver');
const date = new Date();
const dateString = timeSolver.getString(date, "YYYY-MM-DD");

您可以使用此方法获取日期字符串:

getString

W
Williaan Lopes
new Date().toLocaleDateString('pt-br').split( '/' ).reverse( ).join( '-' );

或者

new Date().toISOString().split('T')[0]
new Date('23/03/2020'.split('/').reverse().join('-')).toISOString()
new Date('23/03/2020'.split('/').reverse().join('-')).toISOString().split('T')[0]

尝试这个!


第二个选项可能会显示错误的日期,因为它将以 UTC 时区显示数据。
H
Hashbrown

当 ES2018 滚动时(在 chrome 中工作),您可以简单地对其进行正则表达式

(new Date())
    .toISOString()
    .replace(
        /^(?<year>\d+)-(?<month>\d+)-(?<day>\d+)T.*$/,
        '$<year>-$<month>-$<day>'
    )

2020-07-14

或者,如果您想要没有任何库的非常通用的东西

(new Date())
    .toISOString()
    .match(
        /^(?<yyyy>\d\d(?<yy>\d\d))-(?<mm>0?(?<m>\d+))-(?<dd>0?(?<d>\d+))T(?<HH>0?(?<H>\d+)):(?<MM>0?(?<M>\d+)):(?<SSS>(?<SS>0?(?<S>\d+))\.\d+)(?<timezone>[A-Z][\dA-Z.-:]*)$/
    )
    .groups

这导致提取以下内容

{
    H: "8"
    HH: "08"
    M: "45"
    MM: "45"
    S: "42"
    SS: "42"
    SSS: "42.855"
    d: "14"
    dd: "14"
    m: "7"
    mm: "07"
    timezone: "Z"
    yy: "20"
    yyyy: "2020"
}

您可以像这样使用顶部的 replace(..., '$<d>/$<m>/\'$<yy> @ $<H>:$<MM>') 而不是 .match(...).groups 来获得

14/7/'20 @ 8:45

有几种更简单的方法可以删除在此之前已发布的 toISOString 字符串。对于愿意容忍使用 toISOString 的潜在不准确性的人来说,纯粹的开销和代码膨胀使得这是一个没有人应该考虑的解决方案(无论如何是第一个片段)。
听着,伙计,除非您试图从字面上重新解析日期hundreds of thousands of times in a matter of seconds,否则您不会看到任何差异,所以我不知道您从哪里开始称其为臃肿。与添加到已回答的旧问题中的任何其他 新颖 答案一样;这为读者提供了选择,也许还有知识(“哎呀,我不知道正则表达式可以做到这一点!”)。读者应该知道答案是否适合他们的用例,然后你侮辱他们。
我从来没有提到性能,所以你可以留下关于 100,000 次迭代的争论。我的观点是,早期的答案提供了更简单的技术。
是的,但不可读,或易于扩展。您称其为膨胀,字面意思是 code...that is perceived as unnecessarily long, slow, or otherwise wasteful of resources。 SO 主要是为了知识,所以是的,即使已经回答了字面上的问题,但有时其他人(至少已经字面意义上的 3▲)发现其他角度可能有用!设想。 I don't play the "Fastest Gun In The West" game, so when you see me post a late answer, it is because I have something valuable to offer and I hope that you will acknowledge the care that I take. - 一些伪君子
这里没有什么虚伪的。我很清楚第一个代码段远没有简单地调用 .slice(0,10) 有吸引力。 slice() 更加简洁、直接、易读。我喜欢正则表达式,但不是为了这个问题。看看我怎么没有攻击你作为一个人?我正在判断你对这个问题的回答。
A
Ado Ren
const formatDate = d => [
    d.getFullYear(),
    (d.getMonth() + 1).toString().padStart(2, '0'),
    d.getDate().toString().padStart(2, '0')
].join('-');

您可以使用padstart。

padStart(n, '0') 确保字符串中至少有 n 个字符,并在其前面加上 '0' 直到达到该长度。

join('-') 连接一个数组,在每个元素之间添加“-”符号。

getMonth() 从 0 开始,因此是 +1。


P
Peter Mortensen

我建议使用 formatDate-js 之类的东西,而不是每次都尝试复制它。只需使用支持所有主要 strftime 操作的库即可。

new Date().format("%Y-%m-%d")

J
Julius

不幸的是,JavaScript's Date objectmany pitfalls。任何基于 Date's builtin toISOString 的解决方案都必须与时区混淆,如该问题的其他一些答案中所述。 Temporal.PlainDate from the Temporal proposal 给出了表示 ISO-8601 日期(没有时间)的干净解决方案。自 2021 年 2 月起,您必须选择最适合您的解决方法。

使用带有香草字符串连接的日期

假设您的内部表示基于 Date,您可以执行手动字符串连接。以下代码避免了 Date 的一些缺陷(时区、从零开始的月份、缺少 2 位格式),但可能存在其他问题。

function vanillaToDateOnlyIso8601() {
  // month May has zero-based index 4
  const date = new Date(2014, 4, 11);

  const yyyy = date.getFullYear();
  const mm = String(date.getMonth() + 1).padStart(2, "0"); // month is zero-based
  const dd = String(date.getDate()).padStart(2, "0");

  if (yyyy < 1583) {
    // TODO: decide how to support dates before 1583
    throw new Error(`dates before year 1583 are not supported`);
  }

  const formatted = `${yyyy}-${mm}-${dd}`;
  console.log("vanilla", formatted);
}

将 Date 与帮助库一起使用(例如 date-fns 中的 formatISO)

这是一种流行的方法,但您仍然被迫将日历日期作为 Date, which represents

独立于平台的格式的单个时刻

但是,以下代码应该可以完成工作:

import { formatISO } from "date-fns";

function dateFnsToDateOnlyIso8601() {
  // month May has zero-based index 4
  const date = new Date(2014, 4, 11);
  const formatted = formatISO(date, { representation: "date" });
  console.log("date-fns", formatted);
}

找到一个正确表示日期和时间的库

我希望有一个干净且经过实战考验的库,它可以带来自己精心设计的日期时间表示。此问题中任务的一个有希望的候选者是 LocalDate from @js-joda/core,但该库不如 date-fns 活跃。在使用一些示例代码时,我在添加可选的 @js-joda/timezone 后也遇到了一些问题。

但是,核心功能有效并且对我来说看起来很干净:

import { LocalDate, Month } from "@js-joda/core";

function jodaDateOnlyIso8601() {
  const someDay = LocalDate.of(2014, Month.MAY, 11);
  const formatted = someDay.toString();
  console.log("joda", formatted);
}

使用 Temporal-proposal polyfill 进行实验

不建议将其用于生产,但如果您愿意,可以导入未来:

import { Temporal } from "proposal-temporal";

function temporalDateOnlyIso8601() {
  // yep, month is one-based here (as of Feb 2021)
  const plainDate = new Temporal.PlainDate(2014, 5, 11);
  const formatted = plainDate.toString();
  console.log("proposal-temporal", formatted);
}

请注意,NPM 包 proposal-temporal 已弃用,不应使用。寻找临时 polyfill 的开发人员应检查 github.com/tc39/proposal-temporal#polyfills 以查看推荐的 polyfill 列表,截至目前为 @js-temporal/polyfilltemporal-polyfill
G
Gergo Erdosi

这是一种方法:

var date = Date.parse('Sun May 11,2014');

function format(date) {
  date = new Date(date);

  var day = ('0' + date.getDate()).slice(-2);
  var month = ('0' + (date.getMonth() + 1)).slice(-2);
  var year = date.getFullYear();

  return year + '-' + month + '-' + day;
}

console.log(format(date));

P
Pang

Date.js 非常适合这个。

require("datejs")
(new Date()).toString("yyyy-MM-dd")

P
Peter Mortensen

这些答案都没有让我很满意。我想要一个跨平台解决方案,让我在本地时区度过一天,而无需使用任何外部库。

这就是我想出的:

function localDay(time) {
  var minutesOffset = time.getTimezoneOffset()
  var millisecondsOffset = minutesOffset*60*1000
  var local = new Date(time - millisecondsOffset)
  return local.toISOString().substr(0, 10)
}

这应该在日期引用的时区中以 YYYY-MM-DD 格式返回日期的日期。

例如,localDay(new Date("2017-08-24T03:29:22.099Z")) 将返回 "2017-08-23",即使它已经是 UTC 的 24 日。

您需要 polyfill Date.prototype.toISOString 才能在 Internet Explorer 8 中工作,但它应该在其他任何地方都受支持。


也许值得注意的是,如果您足够落后于 UTC(例如在美国),它只会给您 2017-08-23 。
P
Peter Mortensen

之前的一些答案是可以的,但它们不是很灵活。我想要一些可以真正处理更多边缘情况的东西,所以我接受了@orangleliu 的回答并对其进行了扩展。 https://jsfiddle.net/8904cmLd/1/

function DateToString(inDate, formatString) {
    // Written by m1m1k 2018-04-05

    // Validate that we're working with a date
    if(!isValidDate(inDate))
    {
        inDate = new Date(inDate);
    }

    // See the jsFiddle for extra code to be able to use DateToString('Sun May 11,2014', 'USA');
    //formatString = CountryCodeToDateFormat(formatString);

    var dateObject = {
        M: inDate.getMonth() + 1,
        d: inDate.getDate(),
        D: inDate.getDate(),
        h: inDate.getHours(),
        m: inDate.getMinutes(),
        s: inDate.getSeconds(),
        y: inDate.getFullYear(),
        Y: inDate.getFullYear()
    };

    // Build Regex Dynamically based on the list above.
    // It should end up with something like this: "/([Yy]+|M+|[Dd]+|h+|m+|s+)/g"
    var dateMatchRegex = joinObj(dateObject, "+|") + "+";
    var regEx = new RegExp(dateMatchRegex,"g");
    formatString = formatString.replace(regEx, function(formatToken) {
        var datePartValue = dateObject[formatToken.slice(-1)];
        var tokenLength = formatToken.length;

        // A conflict exists between specifying 'd' for no zero pad -> expand
        // to '10' and specifying yy for just two year digits '01' instead
        // of '2001'.  One expands, the other contracts.
        //
        // So Constrict Years but Expand All Else
        if (formatToken.indexOf('y') < 0 && formatToken.indexOf('Y') < 0)
        {
            // Expand single digit format token 'd' to
            // multi digit value '10' when needed
            var tokenLength = Math.max(formatToken.length, datePartValue.toString().length);
        }
        var zeroPad = (datePartValue.toString().length < formatToken.length ? "0".repeat(tokenLength) : "");
        return (zeroPad + datePartValue).slice(-tokenLength);
    });

    return formatString;
}

示例用法:

DateToString('Sun May 11,2014', 'MM/DD/yy');
DateToString('Sun May 11,2014', 'yyyy.MM.dd');
DateToString(new Date('Sun Dec 11,2014'),'yy-M-d');

漂亮的干净和评论的解决方案。然而,我对第一个论点持怀疑态度,如果不被认为是有效日期,它会被一个新的日期默默地取代。我宁愿把这个“可选默认值”作为第二个参数,并返回某种异常(可能是一个简单的“无效日期格式”返回字符串)以防格式无法识别,这样错误就会清楚地显示到测试人员/用户
S
Stefan Zhelyazkov

如果您使用 momentjs,现在它们包括 a constant for that format YYYY-MM-DD

date.format(moment.HTML5_FMT.DATE)

P
Peter Mortensen

重新格式化日期字符串相当简单,例如

var s = '2014 年 5 月 11 日星期日';函数reformatDate(s) {函数z(n){return ('0' + n).slice(-2)} var months = [,'jan','feb','mar','apr','may ','jun', 'jul','aug','sep','oct','nov','dec']; var b = s.split(/\W+/);返回 b[3] + '-' + z(months.indexOf(b[1].substr(0,3).toLowerCase())) + '-' + z(b[2]); } console.log(reformatDate(s));


A
Andrei

函数 myYmd(D){ var pad = function(num) { var s = '0' + num;返回 s.substr(s.length - 2); } var 结果 = D.getFullYear() + '-' + pad((D.getMonth() + 1)) + '-' + pad(D.getDate());返回结果; } var datemilli = new Date('Sun May 11,2014'); document.write(myYmd(datemilli));


k
kadrian

答案的另一种组合。可读性很好,但有点冗长。

function getCurrentDayTimestamp() {
  const d = new Date();

  return new Date(
    Date.UTC(
      d.getFullYear(),
      d.getMonth(),
      d.getDate(),
      d.getHours(),
      d.getMinutes(),
      d.getSeconds()
    )
  // `toIsoString` returns something like "2017-08-22T08:32:32.847Z"
  // and we want the first part ("2017-08-22")
  ).toISOString().slice(0, 10);
}