Эпоха 14 сентября 1752 г.
Мое прочтение страницы Википедии на Календарь (новый стиль) Act 1750 указывает на дата отсчета эпохи 1752-09-14.
Если мы добавим целую часть вашего входного числа 95906.27600694445
, 95_906L
, мы действительно получим вашу целевую дату 15 апреля 2015 года (в современной календарной системе).
long input = 95_906L;
LocalDate epochCalendarNewStyleActOf1750 = LocalDate.of ( 1752 , Month.SEPTEMBER , 14 );
LocalDate localDate = epochCalendarNewStyleActOf1750.plusDays ( input );
System.out.println ( input + " days from epoch of: " + epochCalendarNewStyleActOf1750 + " is " + localDate );
95906 дней от эпохи: 1752-09-14 по 2015-04-15
Что касается дробного числа, которое, я полагаю, является долей количества секунд в общем 24-часовом дне.
В то время как LocalDate
предназначен только для даты без времени дня, теперь нам нужно время дня, которое представлено нашим дробным числом. Итак, вместо LocalDate
мы переключаемся на OffsetDateTime
.
OffsetDateTime epochCalendarNewStyleActOf1750 = LocalDate.of ( 1752 , Month.SEPTEMBER , 14 ).atStartOfDay ().atOffset ( ZoneOffset.UTC );
Мы используем BigDecimal
, так как double
и Double
технология с плавающей запятой, которая жертвует точностью ради скорости выполнения.
String input = "95906.27600694445";
BigDecimal bd = new BigDecimal ( input );
Вытяните из этого количество целых дней.
long days = bd.toBigInteger ().longValue ();
Работа на долю дня. Извлеките дробное число, вычитая целую часть.
BigDecimal fractionOfADay = bd.subtract ( new BigDecimal ( days ) ); // Extract the fractional number, separate from the integer number.
Мы предполагаем, что эта десятичная дробь представляет собой часть количества секунд в сутках. Таким образом, мы можем умножить на количество секунд в сутках.
BigDecimal secondsFractional = new BigDecimal ( TimeUnit.DAYS.toSeconds ( 1 ) ).multiply ( fractionOfADay );
Из этого извлеките количество целых секунд. Из остатка выведите целое число наносекунд, разрешение классов java.time, включая OffsetDateTime
и Duration
.
long secondsWhole = secondsFractional.longValue ();
long nanos = secondsFractional.subtract ( new BigDecimal ( secondsWhole ) ).multiply ( new BigDecimal ( 1_000_000_000L ) ).longValue ();
Создайте Duration
, чтобы представить количество времени, которое мы хотим добавить к нашей эпохе.
Duration duration = Duration.ofDays ( days ).plusSeconds ( secondsWhole ).plusNanos ( nanos );
Добавьте продолжительность к эпохе, чтобы получить окончательный результат.
OffsetDateTime odt = epochCalendarNewStyleActOf1750.plus ( duration );
Вы можете извлечь объект Instant
из файла OffsetDateTime
.
Instant instant = odt.toInstant();
Дамп на консоль.
System.out.println ( "bd: " + bd );
System.out.println ( "days: " + days );
System.out.println ( "fractionOfADay.toString(): " + fractionOfADay );
System.out.println ( "secondsFractional: " + secondsFractional );
System.out.println ( "secondsWhole: " + secondsWhole );
System.out.println ( "nanos: " + nanos );
System.out.println ( "duration.toString(): " + duration );
System.out.println ( "duration.toDays(): " + duration.toDays () );
System.out.println ( "odt.toString(): " + odt );
Этот код, кажется, работает правильно. Результат здесь соответствует ожиданию, указанному в Вопросе, с точностью до секунды, хотя мы не согласны с долей секунды.
Здесь нет никаких гарантий; этот код только что пришел мне в голову, и он совершенно непроверен и недоказан.
Посмотрите этот код, запущенный в прямом эфире на IdeOne.com.
bd: 95906.27600694445
дней: 95906
фракцияDay.toString(): 0,27600694445
секундыДробная часть: 23847.00000048000
секундВсего: 23847
нано: 480
продолжительность.toString(): PT2301750H37M27.00000048S
продолжительность.toDays(): 95906
odt.toString(): 2015-04-15T06:37:27.000000480Z
Конечно, эта математика может быть проще. Но я подумал, что было бы интересно показать кусочки. Один из более простых способов — умножить 95906.27600694445
BigDecimal на количество секунд в общем 24-часовом дне. Затем отделите полученное целое число от его десятичной дроби и передайте каждое значение Duration.ofSeconds
и Duration::plusNanos
, поскольку это соответствует внутренней модели данных Duration
, общему количеству секунд и общему количеству нано в долях секунды. Мы бы пропустили ту часть, где мы вызывали Duration.ofDays
.
О java.time
Платформа java.time встроен в Java 8 и более поздние версии. Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
и SimpleDateFormat
.
Проект Joda-Time, теперь в режим обслуживания, советует перейти на java.time.
Чтобы узнать больше, см. учебник по Oracle. И поищите множество примеров и пояснений в Stack Overflow. Спецификация: JSR 310.
Где получить классы java.time?
- Java SE 8 and SE 9 and later
- Built-in.
- Часть стандартного Java API со встроенной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 and SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательным полигоном для возможных дополнений к java.time в будущем. Здесь вы можете найти несколько полезных классов, таких как Interval
a>, YearWeek
, YearQuarter
и подробнее.
person
Basil Bourque
schedule
01.03.2017