2010-02-03 32 views

Trả lời

10

Có lẽ không có cách nào dễ dàng hơn là thực hiện cuộc gọi os.system().

import os 
os.system('hwclock --set %s' % date_str) 

hoặc sử dụng lệnh 'date'

import os 
os.system('date -s %s' % date_str) 

hoặc nếu bạn đang hấp hối để làm một số c mã hóa, gói hệ thống các cuộc gọi với uống một lân ... nhưng tôi nghĩ đó sẽ là công việc hơn nó có giá trị.

+0

Nó nên có thể làm - cung cấp trình điều khiển rtc hoặc rtcN hiện diện - qua ioctl, trong fcntl mỗi http: //docs.python .org/library/fcntl.html và rtc (4) (hoặc tài liệu của hạt nhân/rtc.txt) - tuy nhiên, nếu bạn có Python trên hệ thống, hwclock phải dễ dàng. –

+0

Zdav, cảm ơn sự giúp đỡ. Chỉ cần lưu ý: Tôi đang sử dụng busybox và trước hết cần thay đổi đồng hồ hệ thống bằng "os.system ('date -s% s'% date_str)", sau đó đặt đồng hồ hw từ đồng hồ hệ thống với os.system ('hwclock -w). Kính trọng –

0

Một phiên bản cập nhật trên Ubuntu 16.04:

import subprocess 
import shlex 

subprocess.call(shlex.split("timedatectl set-ntp false")) # May be necessary 
subprocess.call(shlex.split("sudo date -s '2 OCT 2006 18:00:00'")) 
subprocess.call(shlex.split("sudo hwclock -w")) 

Lưu ý quan trọng: bạn có thể cần phải thay đổi cài đặt ngày/giờ để tự thiết lập (set-ntp false) hoặc nếu không nó sẽ ngay lập tức thay đổi nó trở lại hiện tại thời gian.

hwclock -w đặt đồng hồ phần cứng dựa trên thời gian hiện tại hệ thống (thiết lập bởi date)

Đó là yêu cầu mà date & hwclock đang chạy như sudo là tốt.

1

Điều này sử dụng ioctl để đặt đồng hồ phần cứng theo yêu cầu (nhưng không phải đồng hồ hệ thống). Nó tránh các quá trình bổ sung nhưng có liên quan nhiều hơn. Tôi đang sử dụng pytzdateutil để xử lý chuyển đổi cục bộ/utc. Vui lòng sử dụng mã (Giấy phép BSD 3 điều khoản). Lấy đồng hồ với get_hwclock() và đặt nó với set_hwclock() ...

from collections import namedtuple 
from datetime import datetime 
from fcntl import ioctl 
import struct 
from dateutil.tz import tzutc 
from pytz import timezone 


# From `uapi/asm-generic/ioctl.h` 
_IOC_NRBITS = 8 
_IOC_TYPEBITS = 8 
_IOC_SIZEBITS = 14 
_IOC_DIRBITS = 2 

_IOC_NRMASK = (1 << _IOC_NRBITS) - 1 
_IOC_TYPEMASK = (1 << _IOC_TYPEBITS) - 1 
_IOC_SIZEMASK = (1 << _IOC_SIZEBITS) - 1 
_IOC_DIRMASK = (1 << _IOC_DIRBITS) - 1 

_IOC_NRSHIFT = 0 
_IOC_TYPESHIFT = _IOC_NRSHIFT + _IOC_NRBITS 
_IOC_SIZESHIFT = _IOC_TYPESHIFT + _IOC_TYPEBITS 
_IOC_DIRSHIFT = _IOC_SIZESHIFT + _IOC_SIZEBITS 

_IOC_NONE = 0 
_IOC_WRITE = 1 
_IOC_READ = 2 


def _IOC(dir, type, nr, size): 
    return ((dir << _IOC_DIRSHIFT) | 
      (type << _IOC_TYPESHIFT) | 
      (nr << _IOC_NRSHIFT) | 
      (size << _IOC_SIZESHIFT)) 


def _IOC_TYPECHECK(t): 
    return len(t) 


def _IO(type, nr): 
    return _IOC(_IOC_NONE, type, nr, 0) 


def _IOR(type, nr, size): 
    return _IOC(_IOC_READ, type, nr, _IOC_TYPECHECK(size)) 


def _IOW(type, nr, size): 
    return _IOC(_IOC_WRITE, type, nr, _IOC_TYPECHECK(size)) 


def to_utc(dtobj): 
    if dtobj.tzinfo is None: 
     dtobj = timezone("UTC").localize(
      dtobj.replace(tzinfo=None) - tzlocal().utcoffset(dtobj)) 
    return dtobj.astimezone(timezone("UTC")) 


class RtcTime(namedtuple(
    # man(4) rtc 
    "RtcTime", 
    "tm_sec tm_min tm_hour " 
    "tm_mday tm_mon tm_year " 
    "tm_wday tm_yday tm_isdst" # Last row is unused. 
)): 

    _fmt = 9 * "i" 

    def __new__(cls, tm_sec=0, tm_min=0, tm_hour=0, 
       tm_mday=0, tm_mon=0, tm_year=0, 
       tm_wday=0, tm_yday=0, tm_isdst=0): 
     return super(RtcTime, cls).__new__(cls, tm_sec, tm_min, tm_hour, 
              tm_mday, tm_mon, tm_year, 
              tm_wday, tm_yday, tm_isdst) 

    def __str__(self): 
     return self.to_datetime().isoformat() 

    @classmethod 
    def from_datetime(cls, dtobj): 
     dt = to_utc(dtobj) 
     return cls(tm_sec=dt.second, tm_min=dt.minute, tm_hour=dt.hour, 
        tm_mday=dt.day, tm_mon=dt.month - 1, tm_year=dt.year - 1900) 

    def to_datetime(self): 
     # From `hwclock.c`. 
     return datetime(
      year=self.tm_year + 1900, month=self.tm_mon + 1, day=self.tm_mday, 
      hour=self.tm_hour, minute=self.tm_min, second=self.tm_sec, 
      tzinfo=tzutc()) 

    def pack(self): 
     return struct.pack(self._fmt, *self) 

    @classmethod 
    def unpack(cls, buffer): 
     return cls._make(struct.unpack(cls._fmt, buffer)) 


# From `uapi/linux/rtc.h` 
rtc_time = RtcTime().pack() 
RTC_RD_TIME = _IOR(ord("p"), 0x09, rtc_time) # 0x80247009 
RTC_SET_TIME = _IOW(ord("p"), 0x0a, rtc_time) # 0x4024700a 
del rtc_time 


def get_hwclock(devrtc="/dev/rtc"): 
    with open(devrtc) as rtc: 
     ret = ioctl(rtc, RTC_RD_TIME, RtcTime().pack()) 
    return RtcTime.unpack(ret).to_datetime() 


def set_hwclock(dt, devrtc="/dev/rtc"): 
    with open(devrtc) as rtc: 
     ioctl(rtc, RTC_SET_TIME, RtcTime.from_datetime(dt).pack()) 
+0

cảm ơn bạn rất nhiều. Thư viện này có sẵn không? Tôi đã nói rằng sao chép và dán là một mẫu xấu. – guettli

+0

@guettli: thư viện: không phải là tôi biết. Theo như tôi quan tâm, tôi sẽ xem xét sao chép và dán ** trong một codebase ** một mẫu xấu. Nhưng sao chép mã của bên thứ ba, lưu nó vào một tập tin với giấy phép thích hợp, và sử dụng trong mã sản xuất là một con thú khác nhau: nó vẫn còn như DRY như bạn sẽ nhận được nó ... –

Các vấn đề liên quan