简体   繁体   English

如何用Joda-Time将1年转换为秒?

[英]How convert 1 year to seconds with Joda-Time?

There is Years class in Joda-Time api,but it does not have any methods for getting seconds or milliseconds (or any methods about converting it to Duration ). Joda-Time api中有Years类,但它没有任何获取秒或毫秒的方法(或任何将其转换为Duration的方法 )。 Also there is a DateTimeConstants with useful constants, but again without any SECONDS_PER_YEAR constant. 还有一个带有有用常量的DateTimeConstants ,但又没有任何SECONDS_PER_YEAR常量。

So how convert 1 year to seconds with joda time? 那么,如何用乔达时间将1年转换为秒呢?

There isn't a constant for the number of seconds in one year because you must first decide a constant for number of days in one year. 一年中的秒数没有常数,因为您必须首先确定一年中的天数的常数。 Using TimeUnit (Java 5+) you could use 使用TimeUnit (Java 5+),您可以使用

System.out.println(TimeUnit.SECONDS.convert(365, TimeUnit.DAYS));
System.out.println(TimeUnit.SECONDS.convert(365, TimeUnit.DAYS)
        + TimeUnit.SECONDS.convert(6, TimeUnit.HOURS));
System.out.println(TimeUnit.SECONDS.convert(366, TimeUnit.DAYS));

to get the number of seconds for 365 days (a typical year), 365.25 days (a "spherical" year) and 366 days (a leap year ). 获取365天(典型年份),365.25天( “球形”年份)和366天(a )的秒数。 I get 我懂了

31536000
31557600
31622400

That could be generalized as an enum like 可以概括为一个enum

public enum YEAR {
    TYPICAL(TimeUnit.SECONDS.convert(365, TimeUnit.DAYS)), //
    SPHERICAL(TimeUnit.SECONDS.convert(365, TimeUnit.DAYS) //
        + TimeUnit.SECONDS.convert(6, TimeUnit.HOURS)), //
    LEAP(TimeUnit.SECONDS.convert(366, TimeUnit.DAYS));
    YEAR(long seconds) {
        this.seconds = seconds;
    }

    long seconds;

    public long getSeconds() {
        return seconds;
    }

    public static YEAR forYear(int year) {
        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
            return LEAP;
        }
        return TYPICAL;
    }
}

And to test it (and reproduce the same output) 并对其进行测试(并重现相同的输出)

public static void main(String[] args) {
    int year = 2016;
    System.out.println(YEAR.forYear(year).getSeconds());
    System.out.println(YEAR.SPHERICAL.getSeconds());
    System.out.println(YEAR.forYear(year + 1).getSeconds());
}

However, as pointed out in the comments, this doesn't account for leap seconds . 但是,正如评论中指出的那样,这并不代表leap秒

tl;dr TL;博士

java.util.concurrent.TimeUnit.DAYS.toSeconds(   // Assuming generic 24-hour days.
    Year.of( 2018 ).length()                    // Get number of days in year, either 365 or 366 (leap year).
)                                               // Return a `long`, a count of seconds in year assuming 24-hour days. 

31536000 31536000

That result is approximate, assuming generic 24-hour days. 假设每天使用24小时,则该结果为近似值。 For a more accurate number, see Exact number of seconds section below. 有关更准确的数字,请参阅下面的“ 精确秒数”部分。

java.time java.time

The modern approach uses the java.time classes. 现代方法使用java.time类。 Note that java.time uses a resolution of nanoseconds , much finer than Joda-Time's milliseconds . 请注意,java.time使用的分辨率为纳秒 ,比Joda-Time的毫秒更好。

The Joda-Time project is now in maintenance mode , with the team advising migration to the java.time classes. Joda-Time项目现在处于维护模式 ,团队建议迁移到java.time类。

Generic number of seconds 通用秒数

If you want a general count of seconds assuming generic 24-hour days, use TimeUnit enum, Year class, and a little math. 如果您希望以秒为单位计算一般的24小时制,请使用TimeUnit枚举, Year类和一些数学知识。 This approach ignores leap second. 这种方法忽略了leap秒。

long secondsPerGenericDay = TimeUnit.DAYS.toSeconds( 1 ) ;  // Assuming 24-hour days.
long days = Year.of( 2018 ).length() ;  // Either 365 or 366 depending on leap year.
long seconds = ( days * secondsPerGenericDay ) ;

…or… …要么…

long secondsInYear = TimeUnit.DAYS.toSeconds( Year.of( 2018 ).length() ) ;

See this code run live at IdeOne.com . 看到此代码在IdeOne.com上实时运行

seconds: 31536000 = secondsInYear: 31536000 秒:31536000 =秒年:31536000

See also correct Answer by Elliott Frisch . 另请参阅Elliott Frisch的 正确答案

Exact number of seconds 确切秒数

If you want exact number of seconds in a year, that can vary by time zone. 如果您想要一年中的确切秒数,则可能会因时区而异。 Anomalies such as Daylight Saving Time (DST) or other changes to a zone's definition made by politicians mean that days can vary in length. 诸如夏令时(DST)或政客对区域定义进行其他更改之类的异常现象意味着天的长度可能会有所不同。 They are not always exactly 24 hours in length. 它们的长度不一定总是24小时。

The approach below does ignore leap seconds , when using a common implementation of Java. 使用Java的常见实现时,以下方法会忽略leap秒 Leap seconds are unpredictable, so you must look to a historical record if you want to add them into your calculation. seconds秒是不可预测的,因此如果要将其添加到计算中,则必须查看历史记录。 In advance, they are scheduled out only a few months. 提前预定了仅几个月。

LocalDate

The LocalDate class represents a date-only value without time-of-day and without time zone. LocalDate类表示没有日期和时区的仅日期值。

A time zone is crucial in determining a date. 时区对于确定日期至关重要。 For any given moment, the date varies around the globe by zone. 在任何给定时刻,日期都会在全球范围内变化。 For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec . 例如, 法国巴黎午夜过后几分钟是新的一天,而在魁北克蒙特利尔仍然是“昨天”。

Specify a proper time zone name in the format of continent/region , such as America/Montreal , Africa/Casablanca , or Pacific/Auckland . continent/region的格式指定正确的时区名称 ,例如America/MontrealAfrica/CasablancaPacific/Auckland Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!). 切勿使用ESTIST等3-4个字母的缩写,因为它们不是真实的时区,不是标准化的,甚至不是唯一的(!)。

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

Year

The Year class can assist. Year可以提供帮助。

Year y = Year.now( z ) ;

LocalDate start = y.atDay( 1 ) ;
LocalDate stop = start.plusYears( 1 ) ;

First moment of the day 一天的第一刻

We need specific moments to calculate seconds. 我们需要特定的时刻来计算秒数。 So need the first moment of each date. 因此需要每个日期的第一刻。

Let java.time determine the first moment. 让java.time确定第一时刻。 Anomalies such as DST mean the day may start at some time other than 00:00. DST之类的异常现象意味着一天可能在00:00以外的某个时间开始。

ZonedDateTime zdtStart = start.atStartOfDay( z ) ;
ZonedDateTime zdtStop = stop.atStartOfDay( z ) ;

Elapsed time 经过时间

We can represent a span of time unattached to the timeline with a resolution of seconds plus fractional second using the Duration class. 我们可以使用Duration类来表示未附加到时间线上的时间跨度,分辨率为秒加小数秒。

Duration d = Duration.between( zdtStart , zdtStop ) ;

Interrogate for the number of whole seconds. 询问整秒数。

long seconds = d.getSeconds() ;

About java.time 关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat . 这些类取代了麻烦的旧的旧式日期时间类,例如java.util.DateCalendarSimpleDateFormat

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes. 现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial . 要了解更多信息,请参见Oracle教程 And search Stack Overflow for many examples and explanations. 并在Stack Overflow中搜索许多示例和说明。 Specification is JSR 310 . 规格为JSR 310

Where to obtain the java.time classes? 在哪里获取java.time类?

The ThreeTen-Extra project extends java.time with additional classes. ThreeTen-Extra项目使用其他类扩展了java.time。 This project is a proving ground for possible future additions to java.time. 该项目为将来可能在java.time中添加内容提供了一个试验场。 You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more . 您可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter ,和更多

What is leap? 什么是飞跃? :) If you ask about days in year it should be 365. Just standard minute, hour and days. :)如果您询问一年中的天数应该是365。只是标准的分钟,小时和天数。 It should be 60*60*24*365 seconds in year, but is there a constant for that? 一年应该是60 * 60 * 24 * 365秒,但是是否有一个常数?

No there isn't. 不,没有。

And the reason is that the number of days (and hence seconds) in a year is not constant. 原因是一年中的天数(因此是秒)不是恒定的。

Really. 真。

It is either 365 or 366 ... depending on which year you are talking about. 它是365还是366 ...取决于您所谈论的年份。

So why didn't they define two constants for the 365 and 366 day cases? 那么为什么不为365天和366天的情况定义两个常量呢? I guess because they deemed it would be harmful. 我猜是因为他们认为这将是有害的。 (For instance, it could lead to people writing applications that assume that every year has 365 days ... and get their interval calculations wrong.) (例如,它可能会导致人编写应用程序,假设每年有365天......并得到他们的间隔算盘打错了。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM