在Python中使用Olson Timezones

时间:2012-10-20 17:12:27

标签: python datetime localization timezone

那么,

时机已到,我正试图逃避拉里·沃尔的噩梦,从Perl转向Python(工作)。为此,我正在通过密集的自学来改造从半夜牛仔编码器,一个人的军队,非文件,我相信你知道像我这样的人(!),对一个和平的Pythonic学生的方式。我也想在这里搞笑,所以请耐心等待。 :/

为此,我正在努力将我每​​天使用的常用代码和实用程序从Perl转换为Python。本周我将使用Perl编写的DateTime相关库加工成一个Python库,该库定义了一个暴露相同契约的类,特别是在Olson数据库的各个时区中创建DateTime对象。这是Perl中的示例。我很难理解Python中的等价物是如何完成的。请注意我在太平洋标准时间上午9:56写这个:

package MyDateTime;

use Moose;
use DateTime;

has day         => (is => 'ro', isa => 'Int');
has hour        => (is => 'ro', isa => 'Int');
has minute      => (is => 'ro', isa => 'Int');
has month       => (is => 'ro', isa => 'Int');
has second      => (is => 'ro', isa => 'Int');
has timezone    => (is => 'ro', isa => 'Str', required => 1);
has timestamp   => (is => 'ro', isa => 'Num', required => 1);
has year        => (is => 'ro', isa => 'Int');

around BUILDARGS => sub {
    my($orig, $class, $timezone, $timestamp) = @_;

    my $datetime = DateTime->from_epoch(
        epoch => $timestamp,
        time_zone => $timezone,
    );

    return $class->$orig(
        day         => sprintf("%02d",$datetime->day),
        hour        => sprintf("%02d",$datetime->hour),
        minute      => sprintf("%02d",$datetime->minute),
        month       => sprintf("%02d",$datetime->month),
        second      => sprintf("%02d",$datetime->second),
        timezone    => $timezone,
        timestamp   => $timestamp,
        year        => $datetime->year,
    );

};

__PACKAGE__->meta->make_immutable;
1;

这将创建一个Perl DateTime对象,其值对应于给定的时区。例如,在单独的脚本中:

#!/usr/bin/env perl

use Moose;
use MyDateTime;

my $timestamp = time();

my $datetime = MyDateTime->new( 'America/Los_Angeles', $timestamp );
print $datetime->hour,"\n";

$datetime = MyDateTime->new( 'America/New_York', $timestamp );
print $datetime->hour,"\n";

打印哪些:

09
12

目前在洛杉矶是上午9点,纽约时间是下午12点。

我在Python中所做的最好的事情如下:

import datetime, pytz, time

class DateTime:
    def __init__(self, timezone, epoch):
        self.timezone = timezone
        self.epoch = epoch
        timezoneobject = pytz.timezone(timezone)
        datetimeobject = datetime.datetime.fromtimestamp( self.epoch )
        self.datetime = timezoneobject.localize(datetimeobject)

    def hour(self):
        return self.datetime.hour

if __name__=='__main__':
    epoch = time.time()
    dt = DateTime('America/Los_Angeles',epoch)
    print dt.datetime
    dt = DateTime('America/New_York',epoch)
    print dt.datetime

打印哪些:

9
9

我不知道这里哪里出错了!是否可以使用pytz在Python中完成相同的操作? (我想是这样!)如果是这样,请帮忙!

由于

1 个答案:

答案 0 :(得分:5)

fromtimestamp可以将时区作为其第二个参数。在这种情况下,fromtimestamp将时间戳解释为相对于该时区,并返回一个时区感知的日期时间对象。


import datetime, pytz, time

utc = pytz.utc
class DateTime:
    def __init__(self, timezone, epoch):
        self.timezone = timezone
        self.epoch = epoch
        timezoneobject = pytz.timezone(timezone)
        self.datetime = datetime.datetime.fromtimestamp(self.epoch, timezoneobject)

    def hour(self):
        return self.datetime.hour

if __name__=='__main__':
    epoch = time.time()
    dt = DateTime('America/Los_Angeles',epoch)
    print dt.hour()
    dt = DateTime('America/New_York',epoch)
    print dt.hour()

产量

10
13

顺便说一句,命名你的类DateTime可能会混淆其他Python程序员(即我!),因为类名听起来与标准库中的datetime模块相同。不同的概念应该具有易于区分的名称。当我指的是另一个名字时,我犯了无数错误。稍后您可以通过为您的班级提供与datetime明显不同的名称来节省一些麻烦。