- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试找出在没有任何库的情况下从纪元秒数(自 NTP 纪元 1900-01-01 00:00 起)转换为日期时间字符串 (MM/DD/YY,hh:mm:ss) 的最佳方法/modules/external functions,因为它们在嵌入式设备上不可用。
我的第一个想法是查看 Python datetime module source code ,但是这对我不是很有用。
我在 Python 中的初始尝试使用从 0001-01-01 到日期的天数转换,使用 getDateFromJulianDay
从 C++ source 适应 Python ,结合取模运算得到时间。它有效,但有更好的方法吗?
def getDateFromJulianDay(julianDay):
# Gregorian calendar starting from October 15, 1582
# This algorithm is from:
# Henry F. Fliegel and Thomas C. van Flandern. 1968.
# Letters to the editor:
# a machine algorithm for processing calendar dates.
# Commun. ACM 11, 10 (October 1968), 657-. DOI=10.1145/364096.364097
# http://doi.acm.org/10.1145/364096.364097
ell = julianDay + 68569;
n = (4 * ell) / 146097;
ell = ell - (146097 * n + 3) / 4;
i = (4000 * (ell + 1)) / 1461001;
ell = ell - (1461 * i) / 4 + 31;
j = (80 * ell) / 2447;
d = ell - (2447 * j) / 80;
ell = j / 11;
m = j + 2 - (12 * ell);
y = 100 * (n - 49) + i + ell;
return y,m,d
# NTP response (integer portion) for Monday, March 25, 2013 at 6:40:43 PM
sec_since_1900 = 3573225643
# 2415021 is the number of days between 0001-01-01 and 1900-01-01,
# the start of the NTP epoch
(year,month,day) = getDateFromJulianDay(2415021 + sec_since_1900/60/60/24)
seconds_into_day = sec_since_1900 % 86400
(hour, sec_past_hour) = divmod(seconds_into_day,3600)
(min, sec) = divmod(sec_past_hour,60)
print 'year:',year,'month:',month,'day:',day
print 'hour:',hour,'min:',min,'sec:',sec
我为什么这样做:我正在从 NTP 服务器获取当前时间,并将这个时间用于更新只接受日期、时间和时区的硬件实时时钟 (RTC):MM/DD/YY,hh:mm:ss ,±zz。我计划在以后实现真正的 NTP 功能。时间同步方法的讨论最好留在别处,例如 this question .
注意事项:
最佳答案
最初提出的 getDateFromJulianDay
函数计算量太大,无法在嵌入式设备上有效使用,包含许多对大型 long
变量的乘法和除法运算,或者如最初编写的那样C++,longlong
variables .
我想我为嵌入式设备找到了一个高效的 epoch to date 算法。
在谷歌搜索无果后,我发现自己又回到了 Stack Overflow,并找到了问题 Converting epoch time to “real” date/time , 询问自写纪元时间的实现并提供合适的算法。这answer问题引用了 gmtime.c source code ,并提供了我编写 Python 转换算法所需的 C 源代码:
/*
* gmtime - convert the calendar time into broken down time
*/
/* $Header: /opt/proj/minix/cvsroot/src/lib/ansi/gmtime.c,v 1.1.1.1 2005/04/21 14:56:05 beng Exp $ */
#include <time.h>
#include <limits.h>
#include "loc_time.h"
struct tm *
gmtime(register const time_t *timer)
{
static struct tm br_time;
register struct tm *timep = &br_time;
time_t time = *timer;
register unsigned long dayclock, dayno;
int year = EPOCH_YR;
dayclock = (unsigned long)time % SECS_DAY;
dayno = (unsigned long)time / SECS_DAY;
timep->tm_sec = dayclock % 60;
timep->tm_min = (dayclock % 3600) / 60;
timep->tm_hour = dayclock / 3600;
timep->tm_wday = (dayno + 4) % 7; /* day 0 was a thursday */
while (dayno >= YEARSIZE(year)) {
dayno -= YEARSIZE(year);
year++;
}
timep->tm_year = year - YEAR0;
timep->tm_yday = dayno;
timep->tm_mon = 0;
while (dayno >= _ytab[LEAPYEAR(year)][timep->tm_mon]) {
dayno -= _ytab[LEAPYEAR(year)][timep->tm_mon];
timep->tm_mon++;
}
timep->tm_mday = dayno + 1;
timep->tm_isdst = 0;
return timep;
}
另外,analysis问题Why is gmtime implemented this way?帮助确认 gmtime
函数相当有效。
使用 raspberryginger.com minix Doxygen documentation site , 我能够找到 gmtime.c 中包含的 C 宏和常量来自 loc_time.h .相关代码片段:
#define YEAR0 1900 /* the first year */
#define EPOCH_YR 1970 /* EPOCH = Jan 1 1970 00:00:00 */
#define SECS_DAY (24L * 60L * 60L)
#define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400)))
#define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
#define FIRSTSUNDAY(timp) (((timp)->tm_yday - (timp)->tm_wday + 420) % 7)
#define FIRSTDAYOF(timp) (((timp)->tm_wday - (timp)->tm_yday + 420) % 7)
#define TIME_MAX ULONG_MAX
#define ABB_LEN 3
extern const int _ytab[2][10];
extern const int _ytab
定义在 misc.c 中:
const int _ytab[2][12] = {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
我发现的其他一些东西:
gmtime
函数从数字 0 开始索引月份、星期几和年份(最大范围分别为 0-11、0-6、0-365),而月中的第几天从数字 1 (1-31) 开始,请参阅 IBM gmtime()
reference .我为 Python 1.5.2+ 重写了 gmtime
函数:
def is_leap_year(year):
return ( not ((year) % 4) and ( ((year) % 100) or (not((year) % 400)) ) )
def year_size(year):
if is_leap_year(year):
return 366
else:
return 365
def ntp_time_to_date(ntp_time):
year = 1900 # EPOCH_YR for NTP
ytab = [ [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
[ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] ]
(dayno,dayclock) = divmod(ntp_time, 86400L)
dayno = int(dayno)
# Calculate time of day from seconds on the day's clock.
(hour, sec_past_hour) = divmod(dayclock,3600)
hour = int(hour)
(min, sec) = divmod(int(sec_past_hour),60)
while (dayno >= year_size(year)):
dayno = dayno - year_size(year)
year = year + 1
month = 1 # NOTE: month range is (1-12)
while (dayno >= ytab[is_leap_year(year)][month]):
dayno = dayno - ytab[is_leap_year(year)][month]
month = month + 1
day = dayno + 1
return (year, month, day, hour, min, sec)
修改我将 C++ gmtime
函数重构为我的 Python 函数 ntp_time_to_date(ntp_time)
:
gmtime
与 ntp_time_to_date
的时间计算:
(dayclock % 3600)/60
和 dayclock/3600
都发生在 divmod(dayclock,3600)
和 的幕后>divmod(sec_past_hour,60)
。divmod(sec_past_hour,60)
通过 dayclock % 60
避免将 dayclock
(0-86399) 取模 60 ,而是在 divmod(sec_past_hour,60)
内对 sec_past_hour
(0-3599) 取模 60。long
中类型强制转换变量,以大大减少代码执行时间。
ntp_time
,自 1900 年以来的秒数 (0-4294967295)dayclock
,一天中的秒数 (0-86399)Python ntp_time_to_date
函数(及其依赖项)在 Telit GC-864 的嵌入式版本 Python 1.5.2+ 以及 Python 2.7.3 上成功运行,当然如果可以,请使用日期时间库。
关于python - 有限嵌入式设备上的纪元秒到日期转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15627307/
iphone设备UDID、iphone设备ID和iphone设备Token之间有什么区别? 通常,当我们使用苹果推送通知服务时,会使用 iPhone 设备 token 。 但我的目标只是识别唯一的 i
我们使用 firebase 从服务器向 Android 和 IOS 设备发送通知,并且我们使用旧版 FCM 发送通知。但是当我们的应用程序在后台时,通知由系统本身处理,因此我们无法通过应用程序处理它。
在 Google 上搜索后,我发现人们说只能通过“MFi 程序”将 iOS 设备与非 iOS 设备连接起来。这是真的吗? 我的项目主要集中于直接通过蓝牙与Arduino设备发送和接收信息。 iOS和非
所以我有一个通用应用程序,我正在设置 UIScrollView 的内容大小。显然,iPhone 和 iPad 上的内容大小会有所不同。如何为 iPad 设置某种尺寸,为 iPhone 和 iPod t
问题:如何在 pod 中使用连接到主机的原始设备作为 block 设备。 我尝试使用类型为“BlockDevice”的“hostPath” volumes: - my-data: hostPath
Implemented GCKDeviceScannerListener Singleton Class on ViewController, however its delegate methods
我有一个 (PhoneGap) 应用程序,它将成功获得 Passbook 通行证,并且还将成功接收与 Passbook 分开的推送通知(当伪造设备 ID 时)。 我遇到的问题是发送给注册设备的设备 I
我正在尝试找到一种方法,通过我目前正在使用的 iOS 应用程序访问我的信标的电池电量。我正在使用 Kontakt 的 iBeacon 设备。我浏览了 Estimote iOS SDK,他们提供了一种实
我正在努力让 CUDA 应用程序也能监控 GPU 的核心温度。可通过 NVAPI 访问该信息。 问题是我想确保在运行代码时监控的是同一个 GPU。 但是,似乎有信息表明我从 NvAPI_EnumPhy
从沙箱模式到生产模式,设备 token 有何不同? 我认为我已将一些设备 token 锁定为生产模式,并且无法将它们从开发中插入。 关于如何检查有什么想法吗? 最佳答案 当您使用开发证书构建应用程序时
目录 /run/user/1000/gvfs 和 ~/.gvfs 分别是空的和不存在的。我的图形文件管理器 (Thunar) 能够检测和访问设备的内部和外部存储器。 命令 gvfs-mount -l
我有一个 Android 平板电脑,它有一个迷你 USB 端口和一个 USB 端口,我想编写一个与 USB key 通信的应用程序。我写了一个demo来找出U盘,但是没有任何反应。 令我不安的是,如果
我们将 PHP 版本从 5.4.25 更改为 5.4.45,并在服务器上安装了 MS SQL 驱动程序。在更改服务器之前,一切正常,但在更改服务器之后,我遇到了 Web 服务问题。我们的身份验证 So
我想知道是否有人使用此 API 在 Android 设备上同时从 2 个后置摄像头捕获图像或视频:https://source.android.com/docs/core/camera/concurr
我正在为客户构建一个物联网解决方案,网络管理员坚持要求设备仅通过访客网络进行连接,该网络有一个强制门户,其中的服务条款必须通过按下 UI 按钮来接受,然后才能获得外部互联网访问。到目前为止,我见过的大
我无法弄清楚这里的格式规则..在我的示例中,代码行太多,无法为每行添加 4 个空格,因此这里是我需要帮助的代码的链接 http://nitemsg.blogspot.com/2011/01/heres
如果我在我的设备上接受推送通知,并且不保存设备 token ,那么我如何在自定义 View 中查看设备 token 或恢复警报 View ? 我删除了应用程序并重新安装,但看不到设备 token 警报
我试图找出在尝试并行比较和复制设备 block 与 pthreads 时我做错了什么。看起来我正在脱离同步并且比较阶段无法正常工作。任何帮助将不胜感激 #ifndef __dbg_h__ #defin
我刚刚写完所有这些内容,但这个红色的小栏告诉我我不能发布图片或两个以上的链接。因此,如果您可以引用 this Imgur album , 那简直太好了。谢谢。 我在这里相对较新,甚至对 android
我需要启用 mysql 常规日志并将其通过 nsf 移动到我系统中的另一个驱动器/设备! 所以,我在 my.cnf 中启用了它: general_log = 1 general_log_fi
我是一名优秀的程序员,十分优秀!