Java毫秒(年)

Java毫秒(年),java,Java,我正在用Java使用毫秒进行一些日期计算,并注意到以下问题: private static final int MILLIS_IN_SECOND = 1000; private static final int SECONDS_IN_MINUTE = 60; private static final int MINUTES_IN_HOUR = 60; private static final int HOURS_IN_DAY = 24; private stati

我正在用Java使用毫秒进行一些日期计算,并注意到以下问题:

private static final int MILLIS_IN_SECOND = 1000;
    private static final int SECONDS_IN_MINUTE = 60;
    private static final int MINUTES_IN_HOUR = 60;
    private static final int HOURS_IN_DAY = 24;
    private static final int DAYS_IN_YEAR = 365; //I know this value is more like 365.24...
    private static final long MILLISECONDS_IN_YEAR = MILLIS_IN_SECOND * SECONDS_IN_MINUTE * MINUTES_IN_HOUR * HOURS_IN_DAY * DAYS_IN_YEAR;


System.out.println(MILLISECONDS_IN_YEAR);  //Returns 1471228928
我知道那一年大约是31556952000毫秒,所以我的乘法不知怎么的就错了


有人能指出我做错了什么吗?我应该用长的吗?

你需要长的。国际贸易总额约为20亿美元

private static final long MILLISECONDS_IN_YEAR = MILLIS_IN_SECOND * ...
右侧的所有操作数都是
int
s,因此乘法是用32位有符号整数完成的,这会溢出。将第一个值转换为
long
,您将获得预期值

private static final long MILLISECONDS_IN_YEAR = (long)MILLIS_IN_SECOND * ...

您正在溢出
int
类型。在Java中,对两个
int
s执行基本算术运算的结果是
int
。操作数的类型决定了这一点,而不是结果变量的类型。尝试:

private static final int MILLIS_IN_SECOND = 1000;
private static final int SECONDS_IN_MINUTE = 60;
private static final int MINUTES_IN_HOUR = 60;
private static final int HOURS_IN_DAY = 24;
private static final int DAYS_IN_YEAR = 365; //I know this value is more like 365.24...
private static final long MILLISECONDS_IN_YEAR = (long) MILLIS_IN_SECOND * SECONDS_IN_MINUTE * MINUTES_IN_HOUR * HOURS_IN_DAY * DAYS_IN_YEAR;
我应该用长的吗

对。问题是,由于
milliss\u IN__SECOND
等都是
int
s,当你将它们相乘时,你会得到
int
。您正在将
int
转换为
long
,但只有在
int
乘法已经导致错误答案之后

要解决此问题,您可以将第一个强制转换为
long

    private static final long MILLISECONDS_IN_YEAR =
        (long)MILLIS_IN_SECOND * SECONDS_IN_MINUTE * MINUTES_IN_HOUR
        * HOURS_IN_DAY * DAYS_IN_YEAR;
试试这个

    int MILLIS_IN_SECOND = 1000;
    int SECONDS_IN_MINUTE = 60;
    int MINUTES_IN_HOUR = 60;
    int HOURS_IN_DAY = 24;
    int DAYS_IN_YEAR = 365;

    long MILLISECONDS_IN_YEAR = (long) MILLIS_IN_SECOND * SECONDS_IN_MINUTE * MINUTES_IN_HOUR * HOURS_IN_DAY * DAYS_IN_YEAR;

    System.out.println(MILLISECONDS_IN_YEAR); // Returns 31536000000

虽然其他人已经指出,但您也可以尝试解决问题:

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
int daysInYear = calendar.getActualMaximum(Calendar.DAY_OF_YEAR);
System.out.println(TimeUnit.DAYS.toMillis(daysInYear));

要解决此问题,您可以将字母L放在第一个字母之后:例如1000L


如果使用android,我建议:

tl;博士 您使用的
int
long
()是导致号码完全错误的原因,
1471228928
是正确的。而且,你们的问题提出了太阳年和日历年的问题

我知道1年=31556952000毫秒

不,那将是一个太阳年的长度,而不是一个日历年。日历年为31536000000毫秒

现代java.time类和
ChronoUnit
可以计算日历年数

Year y = Year.now(                    // Determine the year of the current date (today).
    ZoneId.of( "America/Montreal" )   // Determining the year means determining the current date. And determining a date requires a time zone. For any given moment, the date varies around the globe by zone.
) ;                                   // Returns a `Year` object.


long millisInYear =
ChronoUnit.MILLIS.between( 
    y.atDay( 1 )                      // Get the first of the year. Returns a `LocalDate`. 
     .atStartOfDay(                   // Determine the first moment of the day. Not always 00:00:00 because of anomalies such as Daylight Saving Time (DST).
         ZoneId.of( "America/Montreal" )  
    )                                 // Returns a `ZonedDateTime` object.
    ,
    y.plusYears(1)                    // Move to the following year.
     .atDay( 1 )                      // Get the first of the following year. Returns a `LocalDate`. 
     .atStartOfDay(                   
         ZoneId.of( "America/Montreal" )  
    )                                 // Returns a `ZonedDateTime` object.
) ;
31536000000

31556952000=太阳年 使用的是一个太阳年的近似长度,大约365.2425天24小时。这是地球绕太阳运行所需的时间

数学:

365.2425*24*60*60*1000=31556951999.99996≈ 31556952000毫秒

31536000000=日历年 在西方历法(格里高利历/ISO)中,我们使用了365年的24小时日,忽略了地球绕太阳运行需要额外的四分之一天这一事实。我们通过每四年增加一天(大约是四的倍数,除了可以被100整除但不能被400整除的年份),来弥补差异

考虑到一个365天、24小时的普通年份,并且没有夏时制(DST)等异常情况,日历年的长度为31536000000毫秒。并非如您在问题中所建议的那样
31556952000

31536000000=(365*24*60*60*1000)

366天的闰年将是
31622400000
毫秒

long millisInYear = ChronoUnit.MILLIS.between ( start , stop );
31622400000=(366*24*60*60*1000)

java.time 现代java.time类取代了与最早版本的java捆绑在一起的旧日期时间类。那些旧的类已经被证明是混乱和麻烦的

ChronoUnit
闰年和其他异常可能意味着一年中意外的毫秒数。因此,如果精度在您的情况下很重要,那么您应该让java.time进行实际计算

该类可以计算特定单位的运行时间

long millisInYear = ChronoUnit.MILLIS.between( start , stop );
我们需要确定一年中第一天和下一年的确切开始时间。我们通过查看
LocalDate
类来实现这一点,该类表示一个只包含日期的值,没有一天中的时间,也没有时区

LocalDate startLd = LocalDate.of ( 2015 , 1 , 1 );
LocalDate stopLd = startLd.plusYears ( 1 );
通过指定时区(
ZoneId
),我们可以获得时间线上特定时刻的
zoneDateTime
对象

ZoneId z = ZoneId.of ( "America/Montreal" );
ZonedDateTime start = startLd.atStartOfDay ( z );
ZonedDateTime stop = stopLd.atStartOfDay ( z );
最后,以毫秒为单位计算经过的时间

long millisInYear = ChronoUnit.MILLIS.between ( start , stop );
start.toString():2015-01-01T00:00-05:00[美国/蒙特利尔]

stop.toString():2016-01-01T00:00-05:00[美国/蒙特利尔]

百万年:31536000000


关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

该项目现已启动,建议迁移到类

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*

从哪里获得java.time类

  • 然后
    • 内置的
    • 标准JavaAPI的一部分,带有捆绑实现
    • Java9添加了一些次要功能和修复
    • 大部分java.time功能都在中向后移植到Java6和Java7
    • 更高版本的Android捆绑包实现了java.time类

    • 对于早期的Android(为什么不试试呢?或者查一下32位有符号整数的最大值是多少?@Dave Newton我已经试过了,代码返回了一个我知道不正确的值。一个int在一年中工作几毫秒,但是我计算了错误的值。可能闰年是不相关的…@TonyHopkinson闰年是不相关的。我只是用这个代码在两年之间创建一个随机日期。我使用此日期进行测试,不关心边界条件。因为此页面是在搜索“1年(毫秒)”时出现的,请注意,1年(毫秒)的数值不正确。非闰年的正确值为31536000000,
      long millisInYear = ChronoUnit.MILLIS.between ( start , stop );