为什么有这样的工程原因?在RDBMS的情况下,我想知道它与性能有关,因为“ YEAR”比“ MONTH”更具体,例如:您只有2000年,而每年都有“ January”,这将使按年份优先过滤/排序变得更加容易/快捷,这就是为什么年份第一的原因。
但是我不知道那是否真的有意义……有什么原因吗?根本没有?

评论

@IMil我们可能不喜欢它,但是很多时候它们被存储为字符串。

@candied_orange这很奇怪,尤其是在日期的情况下。

xkcd.com/1179

附带说明一下,这种格式不是那种异类。例如,使用匈牙利语(可能还有其他一些语言)YYYY。 MM。 DD。是默认的书面日期格式,距电脑已经很久了。

在编程中,默认日期格式为“ YYYYMMDD”?如果那是真的,那会很好,但是,并非到处都是这样。 RFC 822和RFC 850以及ANSI C的asctime仍然在许多地方得到广泛使用。 RFC 3339和ISO 8601正在逐渐取代旧格式,这是很好的选择,它们肯定是今后应该使用的格式。更笼统地说,我想说的是ISO 8601基本格式(不带分隔符的普通YYYYMMDD)实际上不如YYYY-MM-DD这样的其他格式常见。

#1 楼

这样,就可以使用默认的排序规则(即按字典顺序)轻松地将日期排序为字符串。

这也是为什么使用两位数字指定月份和日期(如果需要,则添加前导零)的原因)。

实际上,它是ISO 8601定义的日期格式之一。该标准还定义了日期和时间格式2015-03-27T15:26:40Z,它也可以作为字符串排序。 br />但是,YYYYMMDD的另一个好处是可以轻松地(不涉及子字符串或字符替换)将字符串解析为整数,并且仍然对整数使用默认顺序。

评论


@lucaswxp:如果为遵循特定模式的字符串编写特殊情况的比较,则当然可以根据需要将其设置为巴洛克式。这里的问题是,架构的设计使得词法顺序(以及词法数字感知顺序)也是逻辑顺序,因此不需要自定义。

–重复数据删除器
18-09-25在0:48

@lucaswxp您的日期字符串可能不在内存中。实际示例:您已经有一个csv文件,该文件已按ISO日期和每年数百万行的行进行了排序。并且您只想返回某些日期之间的行。您可以逐行(逐行)读取文件,直到到达第一个日期,然后将行加载到内存中,直到到达最后一个日期。您可以跳过文件的其余部分。但是,如果将日期另存为其他格式,或者仅按年份排序,则在关闭文件之前,必须仔细阅读整个年度的记录。

–emptyother
18/09/25在5:00



请注意,破折号在ISO 8601中是可选的,因此YYYYMMDD是ISO 8601。

–马丁·巴(Martin Ba)
18-09-25在11:14

@Benoit已经提出了解决Y10K问题的建议。如果我们仍在使用相同的时代,则将转到AYYYYYMMDD,直到Y100K,这将是BYYYYYYMMDD,CYYYYYYYMMDD,DYYYYYYYYMMDD,EYYYYYYYYYMMDD。此前导字母前缀可确保正确的排序顺序(前提是如果仍使用任何YYYY ...日期,则“ A0YYYY ...”等均为无效表示)。在某些年份中,当年份数字的数目可被三整除时,每次更改字母前缀时,我们都会开始添加三个数字,以确保在宇宙热死之前不会用完字母。

– Monty Harder
18/09/25在15:00



重要的是要注意,使用这种格式,排序不仅“更轻松”。词法(基于字符)的排序与时间排序等效,这意味着您可以在不进行语法分析的情况下进行时间排序。

– jpmc26
18-09-25在15:39



#2 楼

尚未提及,但您很快就会忽略YYYY内部的订单。那已经是几千年,几个世纪,几十年甚至几年了。也就是说,YYYY已经从最长周期到最短周期被命令。 MM和DD也是如此,这就是数字系统的工作原理。

因此,要使字段之间的顺序与字段中的顺序一致,唯一的选择是YYYYMMDD。

正如zahbaz和Arseni Mourzenko指出的那样,YYYYMMDD格式很容易排序。这不是幸运的巧合,这是直接将最长持续时间的字段放在首位(并保持长度固定的直接结果;我们在这里引入了Y10K问题。)

评论


当您在开玩笑时,此代码可能会严重困扰我们8000年。代码的寿命比任何人预期的更长………

–降低
18-09-25在15:42

@deceze ISO8601已经规定了5位数字的年份,但是很有趣的是看看当前哪些DateTime实现允许它。

– Zac Faragher
18-09-26在2:16

@ZacFaragher,我敢肯定我们以后会有足够的时间来实现,而不必着急,对吧?

–ilkkachu
18-09-26在17:46

@deceze为什么解冻我-您是否知道如何治愈癌症?不,是9999年,您知道COBOL。

–user3067860
18-09-28在18:54

您可能希望修正您的错字。千禧年这个单词是千禧年的复数,必须用双N拼写,以匹配拉丁文年金年中的年N。当您仅用一个N拼写错误时,它现在很不愉快地匹配拉丁裔肛门的N个肛门,其含义与英语运动中的借用词相同。简而言之,您总是需要用一种拼写方式进行拼写,这意味着您正在谈论的是数千年而不是数千个“屁眼”。 :)

–基督
18-09-29在16:28

#3 楼


有什么理由吗?


是的。这些软件将使用ISO8601。

ISO 8601与其他日期格式相比具有许多优点:


这是带有规范文档的标准: )
毫不含糊。除非已超过13天,否则mm / dd / yyyy和dd / mm / yyyy可能会造成混淆。
按字典顺序将其排序为升序,因此不需要特殊的日期排序逻辑。这在文件名中特别有用,在文件名中,按字典顺序排序的数字经常会引起混淆(例如1_file, 10_file, 2_file)。
它要求使用4位数字的年份和零填充的月份和年份。这避免了2000年的问题和其他歧义。

关于为什么首先存在ISO 8601的原因,是因为人们在国家/系统之间交换数据时发现日期格式不明确且令人困惑,并且需要明确的东西。

有关基本原理,请参阅规范的介绍。


尽管该领域的ISO建议和标准自1971年以来就可用,但数字的不同形式
日期和时间表示已在不同国家/地区普遍使用。如果这些表示法在各个国家/地区之间互换,则可能会误解数字的含义,从而导致混乱和其他后续错误或损失。本国际标准的目的是
消除误解的风险,并避免造成混淆和后果。

...

本国际标准保留了日期和时间中最常用的表达式及其早期国际标准中的
表示形式,并为实践中使用的某些新
表达式提供了唯一表示形式。它在信息交换中的应用,尤其是在数据处理系统之间的交换
以及相关的设备将消除因误解而产生的错误以及由此产生的成本。
该国际标准的推广不仅将促进跨国际边界的互换,而且将
也将改善软件的可移植性,并且将缓解组织内部以及组织之间的通信问题。该标准将“基本”变体定义为最大程度地减少了定界符的使用。因此,YYYYMMDD是扩展格式YYYY-MM-DD的基本替代。

评论


我不知道ISO 8601除了YYYY-MM-DD之外还允许YYYYMMDD。

–keuleJ
18-09-26在19:12

iso.org/iso-8601-date-and-time-format.html似乎表明YYYY-MM-DD的“扩展格式”是8601的唯一格式?

–奥斯卡·奥斯塔加德(Oskar Austegard)
18-09-27在19:08



@keuleJ在ISO 8601标准中,将诸如YYYYMMDD而不是YYYY-MM-DD之类的分隔符的使用最小化称为“基本”格式变体。

–罗勒·布尔克
18-09-27在21:55



ISO 8601的另外两个好处:(a)易于通过机器进行解析,没有空格字符,没有本地化文本;(b)易于跨文化的人类理解,第一年就很容易识别(如果是当代的话),并且不假设英语。

–罗勒·布尔克
18-09-27在22:06

#4 楼

这是因为其他所有实现方式都模棱两可。

2003年2月1日是什么意思? 2003年1月2日?还是在欧洲:2003年2月1日?如果您使用两位数字表示年份,则更糟,例如01/02/03。

这就是为什么您使用YYYYMMDD的原因,这是使我们能够清晰地传达日期的约定,即20030201作为日期总是很清楚。 (它使排序更容易)

(现在不要将其存储为整数2000万3万2100和1。请确定吗?漂亮吗?)

评论


“ 20030201作为日期总是很清楚”:绝对不是这样。除非您知道使用的格式是YYYYMMDD(或者是YYYYDDMM还是DDMMYYYY?),否则它与“ 01/02/2003”一样含糊不清。您总是需要知道日期的格式;没有“约定”可以使事情变得明确。

– Skomisa
18-09-27在17:20



@skomisa这是非常不正确的。 ISO 8601专门出于您所述的原因定义了国际标准日期格式。其他格式都不是有效的日期格式,并且自19880605起就没有使用过

– K. Alan Bates
18-09-27在20:25



@ K.AlanBates您的日期不明确,除非我们假定应根据ISO 8601对其进行分析。

–停止伤害莫妮卡
18-09-27在21:00

20030201是201AD年3月20日,对吧?

–David Richerby
18-09-27在23:07

@Martijn,但特定于语言。在土耳其,它是Şubat而不是2月(在您认为您的代码有效之前,请始终检查土耳其)。

– NH。
18-09-28在16:43

#5 楼

假设t1和t2是不同的整数,它们代表两次用YYYYMMDD格式写入。然后t1
使用DD和MM优先格式会丢失此顺序。

ISO是IMO唯一明智的格式。 />

评论


除非您永远不会将其存储为整数,否则至少我从未见过或未考虑过它。

–烟斗
18-09-25在10:54

@pipe:相信我,有人会的。我们维护着一个将YYYYMMDD存储为整数的旧系统。该设计可能起源于一些没有明确日期类型的旧数据库系统,并且为了向后兼容而保留了该设计。不好看不要这样

–亨氏
18-09-25在11:19



@pipe我在软件行业的经验是,每当有理智的人想说“但是你永远都不会做X”时,总会有至少一个反例

–约瑟夫·罗杰斯(Joseph Rogers)
18-09-25在13:09

@pipe在数据仓库中,通常使用yyyymmdd整数作为日期表的主键/代理键。

– soapygopher
18-09-25在16:55

@ pipe,DNS区域的序列号是一个32位整数,在区域更改时必须增加。虽然它可能只是一个简单的数字,但常见的习惯用法是使用诸如2018092601之类的数字。然后在feature_test_macros(7)中描述了一些神奇的魔术数字定义,例如具有_POSIX_C_SOURCE> 200809L意味着POSIX.1中的特征-2008支持...

–ilkkachu
18-09-26在17:56

#6 楼

没有提到的一点是,在交互式输入中,这种格式允许控制输入。

如果不知道具体的年份和月份,系统将无法知道一个月是否有28、29、30或31天。当交互式输入命令以年份和月份为准时,它可以检查(最后插入的)日期是否在允许的范围内。

同意,问题主要是关于日期格式,但是可以认为日期格式遵循呈现给用户的格式。

#7 楼

YYYYMMDD订单的日期与订购数字的日期相同:最重要的部分在前。 MMDDYYYY就像将“ 123”写成“二十三十三”。 ,而且进展缓慢。我们通常知道是哪一年。看到年份几乎无关紧要,因此我们将其推后。几个月的变化速度足以保持其重要性。其他文化则对此有所不同。世界上许多人更喜欢DDMMYYYY。

评论


您可能需要改写“我们的文化”,因为在我的文化中是DDMMYYYY,所以它不是您自己的“我们的”文化

– slebetman
18-09-25在5:38

使用MMDDYYYY日期格式的所有国家的综合地图img-9gag-fun.9cache.com/photo/a2mXmGd_700b.jpg

–百富勤
18-09-25在7:02

似乎是一个奇怪的论点:“月份的变化速度足够快以保持其重要性”->为什么不把日期放在第一位,因为这种变化速度甚至更快?

– Wim Deblauwe
18-09-25在8:59

@JoelCoehoorn,很容易做到明确(“在我们的美国文化中”)。 “我们的” /“我们”在这里通常用来表示“ stackexchange社区”。

– AnoE
18/09/25在18:52

究竟。 Stackoverflow是国际性的。您居住在美国并不表示,暗示或什至使其他人也更有可能。您不能对读者在这里的所在地做任何假设,因为他们遍布世界各地。而且,大多数读者既不是您,也不是OP,而是其他在Google上找到您答案的人。这则评论写在与您所生活的大陆不同的大陆上。虽然我们有自己的-嗯-有趣的习惯,但我们肯定在这里不使用MM / DD / YYYY ...

–cmaster-恢复莫妮卡
18-09-25在22:06

#8 楼

已经提到了排序,但是到目前为止,最有用的原因是将它们比较为“字符串”,是的,以类似的方式订购了26个字符的时间戳。

我知道此类比较对于排序至关重要,但是它通常对于2元素排序很有用。

漂亮的格式适用于客户端或排版。

#9 楼

此格式使字符串的字母顺序与日期的时间顺序相同。这是有用的,因为许多工具提供了字母顺序,例如按名称排列文件,但无法从文件名解析任意格式的日期并按其排序。

#10 楼

这是限制性的。想象一下YEAR,MONTH和DAY作为参数,格式为YYYYMMDD,每个参数比前一个更具限制性。

因此,如果要搜索1970年发生的事情,可以通过搜索以"1970*"开头的字符串来实现,但是如果记住是哪个月,则可以添加"197005*"之类的月份。这样,日期的每个“参数”都会为您提供更多具体信息。

这是从不太具体的信息("1970*")转到更具体的信息("19700523")的唯一方法。

评论


并不是一个很好的论据-搜索特定月份而不是特定年份发生的事情是很普遍的。

–立方
18-09-25在14:25

如果1970 *和197005 *表示“ glob”通配符语法,则可以通过搜索glob * 1970或05 * 1970来搜索一堆MMDDYYYY日期。您的答案可能隐含地假设了一些您没有明确提到的额外约束,并且可以通过解释您的假设而得到改善。

– Quuxplusone
18/09/26'上午0:01

这是一种副作用,或者是描述其他答案提到的排序键顺序的另一种方式。但是除非您将其限制为仅搜索前缀,否则此解释会分散。 (更易于索引,但绝不需要)。

– Peter Cordes
18-09-26在8:13



这也意味着您可以使用相对简单的正则表达式来选择日期序列。

–哈珀-恢复莫妮卡
18-10-3在2:43

#11 楼


为什么在编程中,默认日期格式为YYYYMMDD ...


这是一种人类可读的输入和输出格式,所以不一定以这种方式存储。 >
三分之一以上的编程语言是在以英语为主要语言的国家/地区开发的,大多数现代语言都遵循某种描述性的标准-国际日期标准是ISO8601。

更多信息:(TMI?)

随着时间的变化,通常是向前,天数首先递增,然后是月数,最后是年份-如果我们有十进制日期(和十进制),可能会更容易理解时间)-随着时间的流逝,数字越来越大。让人一眼就能看清数字并将其与另一个日期进行比较就更简单了。使用逻辑-基数e实际上具有最低的基数经济性,但不是完整序列最有效或最不容易的方法。 ,虽然YYYYMMDD似乎最有意义,并且您习惯了它,但它在当今并不普遍,在过去最长的时间里也不是那样,但即使在今天,罗马数字仍被普遍用作日期。

提前了解一年会告诉您一年中的天数,这是一年中可以经历的最大时间变化。它可以预先告诉您每个月要遵循的天数(用于在输入期间进行错误检查),如果下一年的输入与您的输入不一致,则允许第一天的输入可能需要备份-这可能会使可访问的输入更加困难。关于日历格式,它也很重要。另请参阅极客日历及其十进制星标。

就计算机而言,很可能会使用UNIX纪元时间,即1970年1月1日(星期四)00:00:00协调世界时(UTC)以来经过的秒数。正好是86400秒另请参阅儒略日。 YYYYMMDD格式只是以自我为中心的人类所偏爱的格式,除非另有说明,否则IAU将一年视为儒略年,即365.25天(3155.576万秒)。

评论


实际上,我见过的几乎每一个人类和软件都更喜欢其他格式。

–停止伤害莫妮卡
18-09-27在20:48

很高兴见到你!我是Dave,我更喜欢YYYYMMDD

–反向工程师
18-10-5在10:38

#12 楼

我看到的这种表示的另一种用法是,您可以将日期存储为整数(即​​在数据库中),每个日期仅使用4个字节。然后,使用YYYYMMDD意味着整数比较(通常是一条机器指令)的结果与所表示日期的比较结果相同。而且它的打印程度中等,易于阅读。在任何主流编程环境中,这一切都不需要任何代码或特殊支持。

如果这些都是您需要处理的大多数日期,那么您需要做很多事情,那么这种格式就具有很大的吸引力。

相比之下,DD / MM / YYYY等常见格式的日期以10个字节作为ASCII字符字符串。 YYYYMMDD字符串将其减少到8,并获得了“比较表示形式与比较日期具有相同的结果”的优点,但是即使这样,基于字符串的比较也是逐个字符而不是单个整数比较。

评论


将日期打包成三个字节很简单。范围0000〜9999需要14位,01〜12需要4位,01〜31需要5位,总共23位。通过还使用三字节数量的剩余位,您可以表示32768年内的日期,并保持一天的分辨率。例如,可以使用它来表示日期范围为公元819年至公元24576年。通过将这些位打包为yyyyyyyyyyyymmmmddddd,十进制表示形式可以直接进行比较(尽管不是直接可读的,但是谁在乎数据库的物理存储?)。

–用户
18-09-27在18:57

#13 楼

月亮由绿色奶酪制成的原因相同:不是。在大多数情况下,默认格式是某种本地化的字符串。有时使用ISO格式,但通常使用破折号以提高可读性。默认情况下很少使用YYYYMMDD(或%Y%m%d中的strftime)。公平地说,我确定我已经看过它,但是现在我想不出一个例子。

Unix日期(GNU核心实用程序)

date


输出:

Wed Sep 26 22:20:57 CEST 2018


Python

import time
print(time.ctime())


输出:

Wed Sep 26 22:27:20 2018


C

#include <stdio.h>
#include <time.h>

int main () {
   time_t curtime;

   time(&curtime);
   printf(ctime(&curtime));
   return(0);
}


输出:

Wed Sep 26 22:40:01 2018


C ++

#include <ctime>
#include <iostream>

int main()
{
    std::time_t result = std::time(nullptr);
    std::cout << std::ctime(&result);
}


输出:

Wed Sep 26 22:51:22 2018


JavaScript

current_date = new Date ( );
current_date;


输出:

Wed Sep 26 2018 23:15:22 GMT+0200 (CEST)


SQLite

SELECT date('now');


输出:

2018-09-26


LibreOffice Calc



数字



OnlyOffice



Python + numpy

import numpy as np
pd.datetime64('now')


输出:

numpy.datetime64('2018-09-26T21:31:55')


Python +熊猫

import pandas as pd
pd.Timestamp('now', unit='s')


输出:

Timestamp('2018-09-26 21:47:01.277114153')


软件工程



apport.log

ERROR: apport (pid 9742) Fri Sep 28 17:39:44 2018: called for pid 1534, signal 6, core limit 0, dump mode 2


alternatives.log

update-alternatives 2018-05-08 15:14:24: run with --quiet --install /usr/bin/awk awk /usr/bin/mawk 5 --slave /usr/share/man/man1/awk.1.gz awk.1.gz /usr/share/man/man1/mawk.1.gz --slave /usr/bin/nawk nawk /usr/bin/mawk --slave /usr/share/man/man1/nawk.1.gz nawk.1.gz /usr/share/man/man1/mawk.1.gz


cups / access.log

localhost - - [28/Sep/2018:16:41:58 +0200] "POST / HTTP/1.1" 200 360 Create-Printer-Subscriptions successful-ok


syslog

Sep 28 16:41:46 pop-os rsyslogd:  [origin software="rsyslogd" swVersion="8.32.0" x-pid="946" x-info="http://www.rsyslog.com"] rsyslogd was HUPed


评论


要添加到您的论据中,有多少种是由于运行了脚本的计算机上的用户设置而采用这种方式格式化的?

– Topher Brink
18-09-27在11:05

第一个不是真正的“ bash”,它是日期程序(它输出Do27。此处为CEST 2018 Sep 22:27:09 CEST。)

–PaŭloEbermann
18-09-27在20:27

@PaŭloEbermann你是对的,我希望现在会更好。正如我所说的,其中许多格式都是本地化的,因此您看到的实际格式将取决于您的本地化选项。

–停止伤害莫妮卡
18-09-27在20:42



尽管此答案的重点对面向最终用户的应用程序是正确的,但对于系统之间的数据交换,数据序列化,消息/数据协议,日志记录,跟踪,调试器等而言并非如此。 ISO 8601标准正迅速成为针对系统管理员和程序员的此类使用的规范。与国际或地区无关的情况也一样。

–罗勒·布尔克
18-09-27在22:01



@BasilBourque谢谢,我添加了在我自己的系统中发现的日志的随机样本。我没有其他类型的示例。但是我不认为面对特定领域默认使用ISO 8601的趋势,面对大量默认使用其他格式的软件,其基本变体使其成为“编程中的默认设置”。

–停止伤害莫妮卡
18-09-28在21:39



#14 楼

到目前为止未提及的另一个好处是,理想的量化(将精确值分配为属于相同的通用值范围)是相对容易且快速的单个操作。

假设您正在编写报告,总结了今天的活动,例如总销售额和销售数量。销售日期和时间存储为YYYYMMDDHHMISS,您只需要保留最左边的8个字符(如果是字符串)或整数除以1,000,000(即下限)即可将日期时间缩短到销售日。

类似地,如果您希望当月的销售量,则只保留最左边的6位数字,或者除以100,000,000

当然,您可以说可以进行任何字符串操作,销售的日期时间为“ 12-25-2018 12:34 pm”可以进行细分和多次操作以获取月份和年份。以数字形式122520181234可以被除法和模化,乘以和除法,最终还产生一个月和一年的时间。.
..但是该代码确实很难编写,阅读,维护和理解..

如果日期格式为MM / DD / YYYY,但即使经过精打细算后,即使是复杂的数据库优化器也可能无法利用where子句的列索引。
相比之下,存储YYYYMMDD表示并希望在2018年12月导致类似iq dateasstring LIKE '201812%'dateasint BETWEEN 20181200 and 20181299的where子句-索引可以很容易地用于

,因此,如果没有专用于日期和字符串/数字表示的数据类型是唯一的选择,以最长的间隔在左边到最短的间隔在某些表示形式中使用和存储时间有很多好处。了解,操作,存储,检索和代码维护的概念