in reply to getting a utc value from julian date

I'd be happy with creating a DateTime object from julian, but I don't see that as one of the options (one can go the other direction).
I tried something like
my $dt = DateTime->today; say $dt, " = ", $dt->jd; $dt->subtract(days => $dt->jd, hours => 12); # days implicitly truncat +ed to int say $dt, " = ", $dt->jd;
and came out with
2015-06-29T00:00:00 = 2457202.5 -4713-11-24T12:00:00 = 0
So,
my $jd_to_convert = 2457205.09613609; my $dt = DateTime->new(year => -4713, month => 11, day =>24, hour => 1 +2)->add(days => $jd_to_convert); say $dt, " = ", $dt->jd;
gives
2015-07-01T12:00:00 = 2457205
(With Time::Piece the method would be the same)

Now you just need to convert the fractional part to h m s...

Update: Hah! DateTime accepts fractional hours, exactitude about 0.15 sec on my system
sub jd2dt { # convert JD to DateTime my $jd_to_convert = shift; my $days = int $jd_to_convert; # that odd date is "julian day zero", converted to "proleptic" gre +gorian calendar my $dt = DateTime->new(year => -4713, month => 11, day =>24, hour +=> 12, time_zone => DateTime::TimeZone->new( name => 'UTC' ))->add(da +ys => $days); $dt->add(hours => 24 * ($jd_to_convert - $days)); return $dt; # 2017-06-13 added this line for clarity }
[further update: added comments and time zone, as JD is relative to UTC]

Replies are listed 'Best First'.
Re^2: getting a utc value from julian date
by Aldebaran (Curate) on Jun 30, 2015 at 04:57 UTC

    Alright, great, soonix, thank you. I can dispense with that longer script and focus on the essential output and simply glean the values. Your formula looks right to me, and I'll test it as best I can. I have to wonder out loud how you were able to cobble it together from scratch so quickly. (I've been puzzling for weeks.) Julian dates aren't the stuff that most people can wrap their heads around. Let's look at a toy script:

    #! /usr/bin/perl use warnings; use strict; use 5.010; use DateTime; use DateTime::TimeZone; my $begin = 2457205.09272861; my $middle = 2457205.09613609; my $end = 2457205.09954643; my $dt1 = jd2dt($begin); say "date1 is $dt1"; my $dt2 = jd2dt($middle); say "date2 is $dt2"; my $dt3 = jd2dt($end); say "date3 is $dt3"; my $dur = $dt3-$dt1; say "dur is $dur"; sub jd2dt { # convert JD to DateTime my $jd_to_convert = shift; my $days = int $jd_to_convert; # that odd date is "julian day zero", converted to "proleptic" gre +gorian calendar my $dt = DateTime->new(year => -4713, month => 11, day =>24, hour +=> 12, time_zone => DateTime::TimeZone->new( name => 'UTC' ))->add(da +ys => $days); $dt->add(hours => 24 * ($jd_to_convert - $days)); say "date is $dt"; }

    Output:

    date is 2015-07-01T14:13:31 date1 is 1 date is 2015-07-01T14:18:26 date2 is 1 date is 2015-07-01T14:23:20 date3 is 1 dur is 0

    How is $dt unity at the end of the subroutine and a well-formed string in main?

    How do I fix my duration calculation to reflect the difference in two dates?

    Thanks again for giving my starwatching a perl infusion.

      How is $dt unity at the end of the subroutine and a well-formed string in main?
      Since we haven't an explicit return statement, the sub returns the return value of say.
      Either remove the say, or add return $dt;
      How do I fix my duration calculation to reflect the difference in two dates?
      After having jd2dt returning a DateTime :-) your $dur is a DateTime::Duration object.
      This doesn't have a stringification method, but you can have it back in various units (with limitations, see its ->in_units method).

      P.S.

      I have to wonder out loud how you were able to cobble it together from scratch so quickly.
      … Julian dates aren't the stuff that most people can wrap their heads around.
      But, but, but, Julian Days have been invented precisely to make date calculations as easy as working with decimal money!

      Updated to remove link rot