Android从数据库中的时间戳添加或删除小时 [英] android adding or removing hour from timestamp in database

查看:172
本文介绍了Android从数据库中的时间戳添加或删除小时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从Android的时间戳中减去几天。

I want to subtract a few days from my timestamp in Android.

我有一个 SQLite 数据库,其日期字段的类型为long。
执行查询时,我说 date = date-(3 * 86400000)时,有时将它转换为可读格式会遇到一个小时的差异日期。

I have an SQLite database with a date field of the type long. When I execute a query where I say date = date - (3 * 86400000) I sometimes experience a one hour difference as a result when converting it to a readable date.

但这怎么可能?

因为我会感到奇怪,如果这是原因,因为您正在使用两个长值进行计算,并且将它们转换回日期时间后,应该不会出现夏令时问题吗?

Because I would find it strange if that's the reason because you are doing calculations with two long values and after converting them back to datetime there shouldn't be a daylight saving issue?

推荐答案

tl; dr



使用现代的 java.time 类。

如果您的意思是日历日期为3天,请执行此操作:

If you meant 3 days as in calendar dates, do this:

Instant                                // Represent a moment in UTC with a resolution of nanoseconds.
.ofEpochSecond( x )                    // Parse some number of whole seconds or milliseconds from the epoch reference of first moment of 1970 in UTC.
.atZone(                               // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone).
    ZoneId.of( "Pacific/Auckland" )    // Assign the time zone by which you want the context of their calendar for adding dates.
)                                      // Returns a `ZonedDateTime` object.
.plus(                                 // Move to another moment by adding a span-of-time.
    Period.ofDays( 3 )                 // Define a span of time as a number of days on the calendar (date) without regard for the length of a day.
)                                      // Returns another `ZonedDateTime` object.
.toInstant()                           // Adjust from a time zone to UTC. Same moment, different wall-clock time.
.toEpochSeconds()                      // or maybe `toEpochMillis` depending on your practice with your `long` number.

将SQL编写为:

SELECT * FROM event_ WHERE when_ >= ? ;  -- Find events occurring later than the passed moment.

在Java中使用JDBC 4.2或更高版本:

In Java with JDBC 4.2 or later:

myPreparedStatement.setObject( 1 , secondsSinceEpoch ) ;  // Pass seconds calculated above.

检索。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;



从时代开始计数



您的自 long 的数量大概是整秒或毫秒的计数。 rel = nofollow noreferrer>纪元参考日期

Count-from-epoch

Your number of type long is presumably a count of whole seconds or milliseconds since an epoch reference date.

如果您选择的纪元恰好是 Unix时间 ,UTC 1970年的第一刻,1970-01-01T00:00:00Z,那么我们可以在Java中解析为 即时 Instant 是UTC时间线上的时刻,分辨率为纳秒。 Instant 在内部是一对数字:从纪元开始算起整秒,再加上几分之一秒(纳秒)。

If your chosen epoch happens to be that used by "Unix time", the first moment of 1970 in UTC, 1970-01-01T00:00:00Z, then we can parse in Java as an Instant. An Instant is a moment on the timeline in UTC with a resolution of nanoseconds. An Instant internally is a pair of numbers: a count of whole seconds since epoch, plus a fraction of a second as a count of nanoseconds.

Instant instant = Instant.ofEpochMilli( x ) ;

…或:

Instant instant = Instant.ofEpochSecond( x ) ;



一天不是 24小时



一天(与日历中的日期一样)与24小时不同。政客定义时区的方式异常,例如夏令时(DST)意味着一天可能是23、23.5、24、25或其他小时数-分钟-秒。

A day is not 24 hours

A day, as in a date on the calendar, is not the same thing as 24 hours. Anomalies in the way politicians define time zones such as Daylight Saving Time (DST) means a day might be 23, 23.5, 24, 25, or some other number of hours-minutes-seconds.

如果要添加24小时的大块,请使用 持续时间

If you want to add chunks of 24-hours, use Duration.

Duration d = Duration.ofDays( 3 ) ;  // `Duration` defines a "day" as being a 24-hours without regard for the calendar dates.

或以小时为单位指定,这与 Duration 类,但会更加清楚您的意图和理解。

Or specify in hours, which has the same result in Duration class but would be more clear as to your intent and understanding.

Duration d = Duration.ofHours( 3 * 24 ) ;  // Same effect as the `Duration.ofDays( 3 )` seen above.

添加到您的 Instant

Instant instantLater = instant.plus( d ) ;



期间



如果您要在日历上增加一天,请使用 期间 类。此类表示若干年-月-日。

Period

If you meant a day as incrementing a day on the calendar, use Period class. This class represents a number of years-months-days.

Period p = Period.ofDays( 3 ) ;  // `Period` defines a day as a date on the calendar without regard for its length in hours.

我们不能在没有考虑的情况下将其添加到 Instant 时区问题。如果将其添加到始终位于UTC中的 Instant 中,我们将使用UTC日历。例如,在UTC值中添加一天可能会在印​​度转化为明天,而在魁北克仍为昨天。时区对于确定日期至关重要。在任何给定时刻,日期都会在全球范围内变化。

We cannot add that to Instant without regard for time zone issues. If added to an Instant which is always in UTC we would be using the calendar of UTC. For example, adding a day to a value in UTC might translate to "tomorrow" in India while still being "yesterday" in Québec. A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone.

如果未指定时区,则JVM隐式应用其当前的默认时区。该默认值可能随时更改在运行时(!),因此您的结果可能会有所不同。最好将您的所需/期望的时区明确指定为参数。

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.

指定正确的时区名称,其格式为大陆/地区,例如美国/蒙特利尔非洲/卡萨布兰卡太平洋/奥克兰。请勿使用2-4个字母的缩写,例如 EST IST ,因为它们不是 真实时区,不是标准化的,甚至不是唯一的(!)。

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  

如果要使用JVM的当前默认时区,请提出要求并作为参数传递。如果省略,则会隐式应用JVM的当前默认值。最好明确一点,因为默认值可以在运行时的任何时候在JVM内任何应用程序的任何线程中的任何代码进行更改。

If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.

将您的 ZoneId 应用于 Instant 以获得 ZonedDateTime

ZonedDateTime zdt = instant.atZone( z ) ;

现在您可以将天数添加到 ZonedDateTime

Now you can add days to the ZonedDateTime and the calendar used by the people of that region will be taken into account.

ZonedDateTime zdtLater = zdt.plus( p ) ;  // By "later" we assume the number of days in the `Period` is positive. Alternatively, a `Period` could go backwards in time with a negative number of days.

要调整回UTC,请提取 Instant 。我们仍然在时间轴上具有相同的时刻,相同的点,但是具有不同的挂钟时间。

To adjust back to UTC, extract a Instant. We still have the same moment, the same point on the timeline, but with a different wall-clock time.

Instant instantLater = zdtLater.toInstant() ;  // Same moment, different wall-clock time.

zdt 和<$之间的经过时间c $ c> zdtLater 可能是,也可能不是小时。如果在该时间段内进行了DST转换,则小时数将为年初的春季中的(((3 * 24)-1),或((3 * 24)+ 1)在秋天的 Fall Back中。

The elapsed time between zdt and zdtLater may or may not be ( 3 * 24 ) hours. If a DST cutover occurred during that time, the number of hours would be either ( ( 3 * 24 ) - 1 ) in the "Spring Ahead" early in the year, or ( ( 3 * 24 ) + 1 ) in the "Fall Back" of the autumn.

java.time 框架。这些类取代了麻烦的旧旧版日期时间类,例如 java.util.Date Calendar ,& SimpleDateFormat

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time 项目,现在处于维护模式 ,建议迁移到 java.time 类。

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

要了解更多信息,请参见 Oracle教程 。并在Stack Overflow中搜索许多示例和说明。规范为 JSR 310

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

您可以直接与数据库交换 java.time 对象。使用符合 JDBC驱动程序 / jeps / 170 rel = nofollow noreferrer> JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql。* 类。

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

在哪里获取java.time类?

Where to obtain the java.time classes?


  • Java SE 8 Java SE 9 Java SE 10 Java SE 11 ,以及更高版本-具有捆绑实现的标准Java API。


    • Java 9添加了一些次要功能和修复。

    • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
      • Java 9 adds some minor features and fixes.

      • 大多数 java.time 功能都反向移植到Java 6& nofollow noreferrer> ThreeTen-Backport

      • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
      • Later versions of Android bundle implementations of the java.time classes.
      • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

      ThreeTen-Extra 项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容打下了基础。您可能会在这里找到一些有用的类,例如 时间间隔 YearWeek YearQuarter 更多

      这篇关于Android从数据库中的时间戳添加或删除小时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆