【问题标题】:Using Olson Timezones in Python在 Python 中使用奥尔森时区
【发布时间】:2012-10-20 17:12:26
【问题描述】:

嗯,

时候到了,我正试图摆脱 Larry Wall 的噩梦,从 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 中完成相同的任务? (我想是的!)如果是这样,请帮忙!

谢谢

【问题讨论】:

    标签: python datetime localization timezone


    【解决方案1】:

    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 的名称,以后可以省去一些麻烦。

    【讨论】:

    • 当然,命名是关键,有什么建议的python风格吗?
    • 最重要的是保持一致,并与您的同事兼容。大多数人(或多或少)遵循PEP8。对于类名,这意味着使用 CamelCase,但您会注意到,标准库本身打破了这一点:datetime.datetimecollections.defaultdict 等。
    猜你喜欢
    • 2015-02-12
    • 1970-01-01
    • 2012-10-23
    • 2012-08-24
    • 2014-08-26
    • 2015-07-30
    • 2012-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多