出生日期:每个地方的出生日期都一样吗?
Date of birth: Same date of birth in every local?
目前正在以毫秒为单位存储用户的出生日期(自 01.01.1970 起)。我是否必须确保它在每个国家/地区都是相同的出生日期,或者在 X 国家/地区是 11 月 11 日而在 Y 国家/地区是 11 月 12 日是否很常见?
如果每个国家/地区的出生日期完全相同是常见的做法,我如何确保我存储的毫秒数始终指向每个国家/地区的同一天?
由您决定将所选出生日期解释为哪个时区以及显示出生日期时使用哪个时区。在我看来,在将出生日期从时间戳转换为可读形式并存储时,始终使用出生地的时区(如果您想收集)是合乎逻辑的。否则,您始终可以使用 GMT 或任何其他时区作为您的约定。这将确保所有国家/地区的所有用户都将看到相同的出生日期,但建议将时区附加到日期表示形式以防止混淆。在创建要存储的时间戳时,您当然可以选择将日期解释为基于 GMT 的日期,然后使用用户定义的时区(可能是用户帐户的时区)呈现出生日期。在这种情况下,每个用户的日期(和时间,如果包括出生时间)将显示不同。
忽略time-of-day
很少有人知道自己出生的time-of-day。所以,不,这种详细程度通常不会被跟踪。你永远不会在护照之类的东西上看到 time-of-birth 和 birth-time-zone。他们跟踪 date-only 值,没有时间和时区。
调酒师、边境管制人员等使用当地当前日期来计算年龄,而没有尝试考虑一天中的时间或调整时区。考虑 partial-day 差异被截断,忽略。
要从一个时区到另一个时区准确地调整时刻,您需要一个日期 和 一个 time-of-day。如果没有 time-of-day,您可能有 23-25 小时的可能时间来表示他们的出生时间。
例如,24 日在巴黎午夜后几分钟(比 UTC 早 1 或 2 小时)出生的孩子在蒙特利尔仍然是“昨天”,即 23 日(比 UTC 晚 4 或 5 小时)。但是,如果该出生发生在 24 日 06:00,那么巴黎和蒙特利尔的日期是相同的(24 日),但在时钟为 7 或 8 的不列颠哥伦比亚省温哥华和西雅图是“昨天”(23 日)比 UTC 晚几个小时。
SQL
在 SQL 中使用类似于标准 DATE 类型的数据类型。
Java
在Java中,使用LocalDate
type. To represent the recurring month and day of the birthday celebration, use the MonthDay
class。
为了与数据库交互,符合 JDBC 4.2 的驱动程序应该能够通过 getObject
和 setObject
方法直接与 LocalDate
一起工作 PreparedStatement
。如果不是,则退回到使用旧的 java.sql.Date
。添加到旧方法的新方法 class 有助于转换。
ISO 8601
生成 date-time 值的字符串表示时,使用 ISO 8601 标准中定义的格式,例如 YYYY-MM-DD
,例如:1960-07-11
。对于没有年份的日期,使用 --MM-DD
,例如:--07-11
。 java.time class中的Javaes在解析和生成字符串时默认使用ISO 8601格式。
强制time-of-day
如果出于某种原因您被迫将 date-only 值放入 date-time 字段,那么您必须设置一些任意值 time-of-day。中午是一种可能。我建议将时间部分设置为一天中的第一刻。
当天的第一刻
请注意,第一个时刻并非总是00:00:00
。夏令时 (DST) 和其他异常情况可能会影响某些时区的午夜。例如,一天的第一时刻可能是 01:00:00
。 Java 可以确定一天中适合特定时区的第一时刻。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
ZonedDateTime startOfToday = today.atStartOfDay( zoneId );
目前正在以毫秒为单位存储用户的出生日期(自 01.01.1970 起)。我是否必须确保它在每个国家/地区都是相同的出生日期,或者在 X 国家/地区是 11 月 11 日而在 Y 国家/地区是 11 月 12 日是否很常见?
如果每个国家/地区的出生日期完全相同是常见的做法,我如何确保我存储的毫秒数始终指向每个国家/地区的同一天?
由您决定将所选出生日期解释为哪个时区以及显示出生日期时使用哪个时区。在我看来,在将出生日期从时间戳转换为可读形式并存储时,始终使用出生地的时区(如果您想收集)是合乎逻辑的。否则,您始终可以使用 GMT 或任何其他时区作为您的约定。这将确保所有国家/地区的所有用户都将看到相同的出生日期,但建议将时区附加到日期表示形式以防止混淆。在创建要存储的时间戳时,您当然可以选择将日期解释为基于 GMT 的日期,然后使用用户定义的时区(可能是用户帐户的时区)呈现出生日期。在这种情况下,每个用户的日期(和时间,如果包括出生时间)将显示不同。
忽略time-of-day
很少有人知道自己出生的time-of-day。所以,不,这种详细程度通常不会被跟踪。你永远不会在护照之类的东西上看到 time-of-birth 和 birth-time-zone。他们跟踪 date-only 值,没有时间和时区。
调酒师、边境管制人员等使用当地当前日期来计算年龄,而没有尝试考虑一天中的时间或调整时区。考虑 partial-day 差异被截断,忽略。
要从一个时区到另一个时区准确地调整时刻,您需要一个日期 和 一个 time-of-day。如果没有 time-of-day,您可能有 23-25 小时的可能时间来表示他们的出生时间。
例如,24 日在巴黎午夜后几分钟(比 UTC 早 1 或 2 小时)出生的孩子在蒙特利尔仍然是“昨天”,即 23 日(比 UTC 晚 4 或 5 小时)。但是,如果该出生发生在 24 日 06:00,那么巴黎和蒙特利尔的日期是相同的(24 日),但在时钟为 7 或 8 的不列颠哥伦比亚省温哥华和西雅图是“昨天”(23 日)比 UTC 晚几个小时。
SQL
在 SQL 中使用类似于标准 DATE 类型的数据类型。
Java
在Java中,使用LocalDate
type. To represent the recurring month and day of the birthday celebration, use the MonthDay
class。
为了与数据库交互,符合 JDBC 4.2 的驱动程序应该能够通过 getObject
和 setObject
方法直接与 LocalDate
一起工作 PreparedStatement
。如果不是,则退回到使用旧的 java.sql.Date
。添加到旧方法的新方法 class 有助于转换。
ISO 8601
生成 date-time 值的字符串表示时,使用 ISO 8601 标准中定义的格式,例如 YYYY-MM-DD
,例如:1960-07-11
。对于没有年份的日期,使用 --MM-DD
,例如:--07-11
。 java.time class中的Javaes在解析和生成字符串时默认使用ISO 8601格式。
强制time-of-day
如果出于某种原因您被迫将 date-only 值放入 date-time 字段,那么您必须设置一些任意值 time-of-day。中午是一种可能。我建议将时间部分设置为一天中的第一刻。
当天的第一刻
请注意,第一个时刻并非总是00:00:00
。夏令时 (DST) 和其他异常情况可能会影响某些时区的午夜。例如,一天的第一时刻可能是 01:00:00
。 Java 可以确定一天中适合特定时区的第一时刻。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
ZonedDateTime startOfToday = today.atStartOfDay( zoneId );