chansen / p5-time-moment

Time::Moment represents an exact moment in time.
32 stars 8 forks source link

offset question #23

Closed jbutlerdp closed 7 years ago

jbutlerdp commented 7 years ago

If I try to get 'now' with a specific offset I still get the same value back as if I called the class without the offset. Is this a bug or intended behavior?

my $tm = Time::Moment->now;
print $tm->epoch; #1484689814

my $tm1 = Time::Moment->now->with_offset_same_local(540);
print $tm1->epoch; #1484689814
chansen commented 7 years ago

Time::Moment->now returns the current date and time from the system clock in the system time zone, with the offset set to the system's time zone offset from UTC.

Your system's time zone offset is 9 hours ahead of UTC and since you are assigning the same offset it doesn't alter the epoch:

my $tm = Time::Moment->from_string('2017-01-18T06:50:14+09:00')
                     ->with_offset_same_local(9*60); # 540
say $tm->epoch; # 1484689814
jbutlerdp commented 7 years ago

But that's the thing, my system time zone is EST (-5:00). I am getting the same value in seconds when I call 'now' with or without the offset.

my $now = Time::Moment->now;
my $now_epoch = Time::Moment->now->epoch;

$now = $now->with_offset_same_local(540);

print $now; #1484744604
print $now_epoch; #1484744604
chansen commented 7 years ago

Could you please provide the output of this script:

use Time::Moment;

my $tm1 = Time::Moment->now;
printf "%s (%d)\n", $tm1->to_string, $tm1->epoch;
my $tm2 = $tm1->with_offset_same_local(540);
printf "%s (%d)\n", $tm2->to_string, $tm2->epoch;
jbutlerdp commented 7 years ago

Here is the output, what I am ultimately trying to get it the current date time in Seoul

date && perl server/bin/time.pl
Wed Jan 18 13:00:42 EST 2017
2017-01-18T13:00:42.194234-05:00 (1484762442)
2017-01-18T13:00:42.194234+09:00 (1484712042)

With this bit of code I get the right time but epoch returns the same as Time::Moment->now.

my $now = Time::Moment->from_epoch($sec, $usec * 1000)->with_offset_same_instant(540) #2017-01-19T03:11:15.221884+09:00
$now->epoch; #1484763075

my $now1  = Time::Moment->now; #2017-01-18T13:11:15.221888-05:00
$now1->epoch; #1484763075
jbutlerdp commented 7 years ago

An update, running that same code inside the web application gives me this result. The date time is right but epoch is not.

2017-01-18T15:40:26.357826-05:00  :: 1484772026
2017-01-19T05:40:26.357826+09:00 :: 1484772026
chansen commented 7 years ago

The instant (epoch) should be the same regardless of the local date and time! You should use a time zone unless you know the time zone doesn't observe Daylight Saving Time. This is documented in the TIME ZONES section the POD. There is also an example in eg/clocks.pl.

use Time::Moment;
use DateTime::TimeZone;

sub convert_from_instant {
    my ($tm, $zone) = @_;
    my $offset = $zone->offset_for_datetime($tm) / 60;
    return $tm->with_offset_same_instant($offset);
}

my @zones = (
  'America/New_York',
  'Asia/Seoul',
);

my $now = Time::Moment->now;
foreach my $name (@zones) {
  my $zone = DateTime::TimeZone->new(name => $name);
  my $time = convert_from_instant($now, $zone);
  printf "%s (%d)\n", $time->to_string, $time->epoch;
}

Output:

2017-01-18T15:40:26.357826-05:00 (1484772026)
2017-01-19T05:40:26.357826+09:00 (1484772026)
jbutlerdp commented 7 years ago

Thanks. I came up with a a workaround, what I ended up doing was getting Time::Moment->now->epoch and adding the offset ($zone->offset_for_datetime($tm)) to that to get the time in Korea.

chansen commented 7 years ago

There is no need for a "workaround", if you think there is you are using the API incorrectly and likely to have bugs in your code.

-- chansen