/* package whatever; // don't place package name! */
import java.util.* ;
import java.lang.* ;
import java.io.* ;
import java.time.* ;
import java.time.temporal.* ;
import java.time.format.* ;
import java.math.BigDecimal ;
import java.math.RoundingMode ;
import java.util.Locale ;
import java.util.concurrent.TimeUnit ;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone {
Ideone app = new Ideone ( ) ;
app.doIt ( ) ;
}
public void doIt ( ) {
System .
out .
println ( "running doIt at: " + ZonedDateTime.
now ( ) ) ; Instant instant = this .convertModifiedJulianDaysToInstant ( input ) ;
BigDecimal output
= this .
convertInstantToModifiedJulianDays ( instant
) ;
System .
out .
println ( "input.toString(): " + input
) ; System .
out .
println ( "instant.toString(): " + instant
) ; System .
out .
println ( "output.toString(): " + output
) ;
}
public Instant convertModifiedJulianDaysToInstant
( BigDecimal modJulDays
) { Instant epoch = OffsetDateTime.of ( 1858 , 11 , 17 , 0 , 0 , 0 , 0 , ZoneOffset.UTC ) .toInstant ( ) ; // TODO: Make into a constant to optimize.
long days = modJulDays.toBigInteger ( ) .longValue ( ) ;
BigDecimal fractionOfADay
= modJulDays.
subtract ( new BigDecimal ( days
) ) ; // Extract the fractional number, separate from the integer number. BigDecimal secondsFractional
= new BigDecimal ( TimeUnit.
DAYS .
toSeconds ( 1 ) ) .
multiply ( fractionOfADay
) ; long secondsWhole = secondsFractional.longValue ( ) ;
long nanos
= secondsFractional.
subtract ( new BigDecimal ( secondsWhole
) ) .
multiply ( new BigDecimal ( 1 _000_000_000L
) ) .
longValue ( ) ; Duration duration = Duration.ofDays ( days ) .plusSeconds ( secondsWhole ) .plusNanos ( nanos ) ;
Instant instant = epoch.plus ( duration ) ;
return instant;
}
public BigDecimal convertInstantToModifiedJulianDays
( Instant instant
) { Instant epoch = OffsetDateTime.of ( 1858 , 11 , 17 , 0 , 0 , 0 , 0 , ZoneOffset.UTC ) .toInstant ( ) ; // TODO: Make into a constant to optimize.
Duration duration = Duration.between ( epoch, instant ) ;
long wholeDays = duration.toDays ( ) ;
Duration durationRemainder = duration.minusDays ( wholeDays ) ;
System .
out .
println ( "durationRemainder: " + durationRemainder
) ;
BigDecimal partialDayInNanosBd
= new BigDecimal ( durationRemainder.
toNanos ( ) ) ; // Convert entire duration to a total number of nanoseconds. BigDecimal nanosInADayBd
= new BigDecimal ( TimeUnit.
DAYS .
toNanos ( 1 ) ) ; // How long is a standard day in nanoseconds? System .
out .
println ( "nanosInaDayBd: " + nanosInADayBd
+ " partialDayInNanosBd: " + partialDayInNanosBd
) ; int scale = 9 ; // Maximum number of digits to the right of the decimal point.
BigDecimal partialDayBd
= partialDayInNanosBd.
divide ( nanosInADayBd
) ; // Get a fraction by dividing a total number of nanos in a day by our partial day of nanos. System .
out .
println ( "partialDayBd: " + partialDayBd
) ; BigDecimal result
= wholeDaysBd.
add ( partialDayBd
) ; return result;
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CmltcG9ydCBqYXZhLmlvLio7CgppbXBvcnQgamF2YS50aW1lLio7CmltcG9ydCBqYXZhLnRpbWUudGVtcG9yYWwuKjsKaW1wb3J0IGphdmEudGltZS5mb3JtYXQuKjsKaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOwppbXBvcnQgamF2YS5tYXRoLlJvdW5kaW5nTW9kZTsKaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdDsKCgovKiBOYW1lIG9mIHRoZSBjbGFzcyBoYXMgdG8gYmUgIk1haW4iIG9ubHkgaWYgdGhlIGNsYXNzIGlzIHB1YmxpYy4gKi8KY2xhc3MgSWRlb25lIHsKCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbiAoIFN0cmluZ1tdIGFyZ3MgKSB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbiB7CgogICAgICAgIElkZW9uZSBhcHAgPSBuZXcgSWRlb25lICggKTsKICAgICAgICBhcHAuZG9JdCAoICk7CiAgICB9CgogICAgcHVibGljIHZvaWQgZG9JdCAoICkgewoKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4gKCAicnVubmluZyBkb0l0IGF0OiAiICsgWm9uZWREYXRlVGltZS5ub3cgKCApICk7CiAgICAgICAgQmlnRGVjaW1hbCBpbnB1dCA9IG5ldyBCaWdEZWNpbWFsICggIjU3ODMxLjUiICk7CiAgICAgICAgSW5zdGFudCBpbnN0YW50ID0gdGhpcy5jb252ZXJ0TW9kaWZpZWRKdWxpYW5EYXlzVG9JbnN0YW50ICggaW5wdXQgKTsKICAgICAgICBCaWdEZWNpbWFsIG91dHB1dCA9IHRoaXMuY29udmVydEluc3RhbnRUb01vZGlmaWVkSnVsaWFuRGF5cyAoIGluc3RhbnQgKTsKCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICggImlucHV0LnRvU3RyaW5nKCk6ICIgKyBpbnB1dCApOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiAoICJpbnN0YW50LnRvU3RyaW5nKCk6ICIgKyBpbnN0YW50ICk7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICggIm91dHB1dC50b1N0cmluZygpOiAiICsgb3V0cHV0ICk7CgogICAgfQoKICAgIHB1YmxpYyBJbnN0YW50IGNvbnZlcnRNb2RpZmllZEp1bGlhbkRheXNUb0luc3RhbnQgKCBCaWdEZWNpbWFsIG1vZEp1bERheXMgKSB7CiAgICAgICAgSW5zdGFudCBlcG9jaCA9IE9mZnNldERhdGVUaW1lLm9mICggMTg1OCwgMTEsIDE3LCAwLCAwLCAwLCAwLCBab25lT2Zmc2V0LlVUQyApLnRvSW5zdGFudCAoICk7IC8vIFRPRE86IE1ha2UgaW50byBhIGNvbnN0YW50IHRvIG9wdGltaXplLgogICAgICAgIGxvbmcgZGF5cyA9IG1vZEp1bERheXMudG9CaWdJbnRlZ2VyICggKS5sb25nVmFsdWUgKCApOwogICAgICAgIEJpZ0RlY2ltYWwgZnJhY3Rpb25PZkFEYXkgPSBtb2RKdWxEYXlzLnN1YnRyYWN0ICggbmV3IEJpZ0RlY2ltYWwgKCBkYXlzICkgKTsgLy8gRXh0cmFjdCB0aGUgZnJhY3Rpb25hbCBudW1iZXIsIHNlcGFyYXRlIGZyb20gdGhlIGludGVnZXIgbnVtYmVyLgogICAgICAgIEJpZ0RlY2ltYWwgc2Vjb25kc0ZyYWN0aW9uYWwgPSBuZXcgQmlnRGVjaW1hbCAoIFRpbWVVbml0LkRBWVMudG9TZWNvbmRzICggMSApICkubXVsdGlwbHkgKCBmcmFjdGlvbk9mQURheSApOwogICAgICAgIGxvbmcgc2Vjb25kc1dob2xlID0gc2Vjb25kc0ZyYWN0aW9uYWwubG9uZ1ZhbHVlICggKTsKICAgICAgICBsb25nIG5hbm9zID0gc2Vjb25kc0ZyYWN0aW9uYWwuc3VidHJhY3QgKCBuZXcgQmlnRGVjaW1hbCAoIHNlY29uZHNXaG9sZSApICkubXVsdGlwbHkgKCBuZXcgQmlnRGVjaW1hbCAoIDFfMDAwXzAwMF8wMDBMICkgKS5sb25nVmFsdWUgKCApOwogICAgICAgIER1cmF0aW9uIGR1cmF0aW9uID0gRHVyYXRpb24ub2ZEYXlzICggZGF5cyApLnBsdXNTZWNvbmRzICggc2Vjb25kc1dob2xlICkucGx1c05hbm9zICggbmFub3MgKTsKICAgICAgICBJbnN0YW50IGluc3RhbnQgPSBlcG9jaC5wbHVzICggZHVyYXRpb24gKTsKICAgICAgICByZXR1cm4gaW5zdGFudDsKICAgIH0KCiAgICBwdWJsaWMgQmlnRGVjaW1hbCBjb252ZXJ0SW5zdGFudFRvTW9kaWZpZWRKdWxpYW5EYXlzICggSW5zdGFudCBpbnN0YW50ICkgewogICAgICAgIEluc3RhbnQgZXBvY2ggPSBPZmZzZXREYXRlVGltZS5vZiAoIDE4NTgsIDExLCAxNywgMCwgMCwgMCwgMCwgWm9uZU9mZnNldC5VVEMgKS50b0luc3RhbnQgKCApOyAvLyBUT0RPOiBNYWtlIGludG8gYSBjb25zdGFudCB0byBvcHRpbWl6ZS4KICAgICAgICBEdXJhdGlvbiBkdXJhdGlvbiA9IER1cmF0aW9uLmJldHdlZW4gKCBlcG9jaCwgaW5zdGFudCApOwogICAgICAgIGxvbmcgd2hvbGVEYXlzID0gZHVyYXRpb24udG9EYXlzICggKTsKICAgICAgICBEdXJhdGlvbiBkdXJhdGlvblJlbWFpbmRlciA9IGR1cmF0aW9uLm1pbnVzRGF5cyAoIHdob2xlRGF5cyApOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiAoICJkdXJhdGlvblJlbWFpbmRlcjogIiArIGR1cmF0aW9uUmVtYWluZGVyICk7CgogICAgICAgIEJpZ0RlY2ltYWwgd2hvbGVEYXlzQmQgPSBuZXcgQmlnRGVjaW1hbCAoIHdob2xlRGF5cyApOwogICAgICAgIEJpZ0RlY2ltYWwgcGFydGlhbERheUluTmFub3NCZCA9IG5ldyBCaWdEZWNpbWFsICggZHVyYXRpb25SZW1haW5kZXIudG9OYW5vcyAoICkgKTsgLy8gQ29udmVydCBlbnRpcmUgZHVyYXRpb24gdG8gYSB0b3RhbCBudW1iZXIgb2YgbmFub3NlY29uZHMuCiAgICAgICAgQmlnRGVjaW1hbCBuYW5vc0luQURheUJkID0gbmV3IEJpZ0RlY2ltYWwgKCBUaW1lVW5pdC5EQVlTLnRvTmFub3MgKCAxICkgKTsgIC8vIEhvdyBsb25nIGlzIGEgc3RhbmRhcmQgZGF5IGluIG5hbm9zZWNvbmRzPwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiAoICJuYW5vc0luYURheUJkOiAiICsgbmFub3NJbkFEYXlCZCArICIgIHBhcnRpYWxEYXlJbk5hbm9zQmQ6ICIgKyBwYXJ0aWFsRGF5SW5OYW5vc0JkICk7CiAgICAgICAgaW50IHNjYWxlID0gOTsgLy8gTWF4aW11bSBudW1iZXIgb2YgZGlnaXRzIHRvIHRoZSByaWdodCBvZiB0aGUgZGVjaW1hbCBwb2ludC4KICAgICAgICBCaWdEZWNpbWFsIHBhcnRpYWxEYXlCZCA9IHBhcnRpYWxEYXlJbk5hbm9zQmQuZGl2aWRlICggbmFub3NJbkFEYXlCZCApOyAvLyBHZXQgYSBmcmFjdGlvbiBieSBkaXZpZGluZyBhIHRvdGFsIG51bWJlciBvZiBuYW5vcyBpbiBhIGRheSBieSBvdXIgcGFydGlhbCBkYXkgb2YgbmFub3MuCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICggInBhcnRpYWxEYXlCZDogIiArIHBhcnRpYWxEYXlCZCApOwogICAgICAgIEJpZ0RlY2ltYWwgcmVzdWx0ID0gd2hvbGVEYXlzQmQuYWRkICggcGFydGlhbERheUJkICk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCn0=