繁体   English   中英

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

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

Joda-Time api中有Years类,但它没有任何获取秒或毫秒的方法(或任何将其转换为Duration的方法 )。 还有一个带有有用常量的DateTimeConstants ,但又没有任何SECONDS_PER_YEAR常量。

那么,如何用乔达时间将1年转换为秒呢?

一年中的秒数没有常数,因为您必须首先确定一年中的天数的常数。 使用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));

获取365天(典型年份),365.25天( “球形”年份)和366天(a )的秒数。 我懂了

31536000
31557600
31622400

可以概括为一个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;
    }
}

并对其进行测试(并重现相同的输出)

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());
}

但是,正如评论中指出的那样,这并不代表leap秒

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

假设每天使用24小时,则该结果为近似值。 有关更准确的数字,请参阅下面的“ 精确秒数”部分。

java.time

现代方法使用java.time类。 请注意,java.time使用的分辨率为纳秒 ,比Joda-Time的毫秒更好。

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

通用秒数

如果您希望以秒为单位计算一般的24小时制,请使用TimeUnit枚举, Year类和一些数学知识。 这种方法忽略了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 ) ;

…要么…

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

看到此代码在IdeOne.com上实时运行

秒:31536000 =秒年:31536000

另请参阅Elliott Frisch的 正确答案

确切秒数

如果您想要一年中的确切秒数,则可能会因时区而异。 诸如夏令时(DST)或政客对区域定义进行其他更改之类的异常现象意味着天的长度可能会有所不同。 它们的长度不一定总是24小时。

使用Java的常见实现时,以下方法会忽略leap秒 seconds秒是不可预测的,因此如果要将其添加到计算中,则必须查看历史记录。 提前预定了仅几个月。

LocalDate

LocalDate类表示没有日期和时区的仅日期值。

时区对于确定日期至关重要。 在任何给定时刻,日期都会在全球范围内变化。 例如, 法国巴黎午夜过后几分钟是新的一天,而在魁北克蒙特利尔仍然是“昨天”。

continent/region的格式指定正确的时区名称 ,例如America/MontrealAfrica/CasablancaPacific/Auckland 切勿使用ESTIST等3-4个字母的缩写,因为它们不是真实的时区,不是标准化的,甚至不是唯一的(!)。

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

Year

Year可以提供帮助。

Year y = Year.now( z ) ;

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

一天的第一刻

我们需要特定的时刻来计算秒数。 因此需要每个日期的第一刻。

让java.time确定第一时刻。 DST之类的异常现象意味着一天可能在00:00以外的某个时间开始。

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

经过时间

我们可以使用Duration类来表示未附加到时间线上的时间跨度,分辨率为秒加小数秒。

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

询问整秒数。

long seconds = d.getSeconds() ;

关于java.time

java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧的旧式日期时间类,例如java.util.DateCalendarSimpleDateFormat

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

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

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。 该项目为将来可能在java.time中添加内容提供了一个试验场。 您可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter ,和更多

什么是飞跃? :)如果您询问一年中的天数应该是365。只是标准的分钟,小时和天数。 一年应该是60 * 60 * 24 * 365秒,但是是否有一个常数?

不,没有。

原因是一年中的天数(因此是秒)不是恒定的。

真。

它是365还是366 ...取决于您所谈论的年份。

那么为什么不为365天和366天的情况定义两个常量呢? 我猜是因为他们认为这将是有害的。 (例如,它可能会导致人编写应用程序,假设每年有365天......并得到他们的间隔算盘打错了。)

暂无
暂无

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

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