tl;dr
The Answer by Ruakh is correct about your use of int
vs long
(integer overflow) being the cause of a totally wrong number, 1471228928
. But furthermore, your Question raises issue of solar year versus calendar year.
I know that that 1 Year = 31556952000 Milliseconds
No, that would be the length of a solar year, not a calendar year. A calendar year is 31,536,000,000
milliseconds.
The modern java.time classes and ChronoUnit
can calculate the calendar year number.
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
31,556,952,000 = Solar year
Your source is using an approximation of the length of a solar year, about 365.2425 24-hour days. This is the amount of time it takes the earth to orbit the sun.
The math:
365.2425 * 24 * 60 * 60 * 1000 = 31,556,951,999.999996 ≈ 31,556,952,000 ms
See this calculator.
31,536,000,000 = Calendar year
In the Western calendar (Gregorian/ISO), we use years of an even 365 24-hour days, ignoring the fact that the earth's orbit around the sun takes an extra quarter day. We make up for the discrepancy by inserting an extra day every four years (roughly, years which are multiples of four with the exception of years divisible by 100 but not by 400), the Leap Day.
Considering a plain year of 365 days with 24-hour days and no anomalies to account for such as Daylight Saving Time (DST), a calendar year is 31,536,000,000
milliseconds long. Not 31,556,952,000
as you suggest in your Question.
31,536,000,000 = ( 365 * 24 * 60 * 60 * 1000 )
See this calculator.
A Leap Year with 366 days will be 31,622,400,000
milliseconds.
31,622,400,000 = ( 366 * 24 * 60 * 60 * 1000 )
java.time
The modern java.time classes supplant the old date-time classes bundled with the earliest versions of Java. Those old classes have proven to be confusing and troublesome.
ChronoUnit
Leap year and other anomalies might mean an unexpected number of milliseconds in a year. So you should let java.time do an actual calculation, if precision is important in your situation.
The ChronoUnit
class can calculate elapsed time in a certain unit.
long millisInYear = ChronoUnit.MILLIS.between( start , stop );
We need to determine the exact moment of the start of the first day day of the year and of the following year. We do that by going through the LocalDate
class, which represents a date-only value without a time-of-day and without a time zone.
LocalDate startLd = LocalDate.of ( 2015 , 1 , 1 );
LocalDate stopLd = startLd.plusYears ( 1 );
By assigning a time zone (ZoneId
) we get ZonedDateTime
objects for specific moments on the timeline.
ZoneId z = ZoneId.of ( "America/Montreal" );
ZonedDateTime start = startLd.atStartOfDay ( z );
ZonedDateTime stop = stopLd.atStartOfDay ( z );
Lastly, calculate the elapsed time in milliseconds.
long millisInYear = ChronoUnit.MILLIS.between ( start , stop );
start.toString(): 2015-01-01T00:00-05:00[America/Montreal]
stop.toString(): 2016-01-01T00:00-05:00[America/Montreal]
millisInYear: 31536000000
About java.time
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
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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.
Where to obtain the java.time classes?
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.