文档章节

erlang国际化时间转换(ISO 8601)

nao
 nao
发布于 2016/11/18 13:12
字数 1606
阅读 18
收藏 0
点赞 0
评论 0

** 什么是ISO 8601**

国际标准化组织的国际标准ISO 8601是日期和时间表示方法,全称为<<数据存储和交互形式 信息交换 日期和时间的表示方法>>。目前最新为第三版ISO8601:2004, 第一版为ISO8601:1988, 第二版为ISO8601:2000。

日期和时间的组合表示法

合并表示时,要在时间前面加一大写字母T, 如要表示北京时间2004年5月3日下午5点30分8秒,可以写成2004-05-03T17:30:08+08:00或20040503T173008+08。

详细内容请查阅百度百科

https://en.wikipedia.org/wiki/ISO_8601

输入图片说明

erlang时间与日期处理

http://www.cnblogs.com/me-sa/archive/2012/05/17/erlang-calendar-date-time.html

** iso8601库**

下面把德国时间转换为北京时间

输入图片说明

世界各国时间转换网址:

http://cn.piliapp.com/time-now/converter/

使用iso8601库进行转换结果: 输入图片说明

代码如下:

-module(iso8601).

-export([add_time/4,
         format/1,
         parse/1,
         parse_exact/1]).

-export_types([timestamp/0]).
-define(MIDNIGHT, {0,0,0}).
-define(V, proplists:get_value).

-type datetime_plist() :: list({atom(), integer()}).
-type maybe(A) :: undefined | A.
-type timestamp() :: {MegaSecs::integer(),
                      Secs::integer(),
                      MicroSecs::integer() | float()}.

%% API

-spec add_time (calendar:datetime(), integer(), integer(), integer())
               -> calendar:datetime().
%% @doc Add some time to the supplied `calendar:datetime()'.
add_time(Datetime, H, M, S) ->
    apply_offset(Datetime, H, M, S).

-spec format (calendar:datetime() | timestamp()) -> binary().
%% @doc Convert a `util:timestamp()' or a calendar-style `{date(), time()}'
%% tuple to an ISO 8601 formatted string. Note that this function always
%% returns a string with no offset (i.e., ending in "Z").
format({_,_,_}=Timestamp) ->
    format(calendar:now_to_datetime(Timestamp));
format({{Y,Mo,D}, {H,Mn,S}}) when is_float(S) ->
    FmtStr = "~4.10.0B-~2.10.0B-~2.10.0BT~2.10.0B:~2.10.0B:~9.6.0fZ",
    IsoStr = io_lib:format(FmtStr, [Y, Mo, D, H, Mn, S]),
    list_to_binary(IsoStr);
format({{Y,Mo,D}, {H,Mn,S}}) ->
    FmtStr = "~4.10.0B-~2.10.0B-~2.10.0BT~2.10.0B:~2.10.0B:~2.10.0BZ",
    IsoStr = io_lib:format(FmtStr, [Y, Mo, D, H, Mn, S]),
    list_to_binary(IsoStr).

-spec parse (string()) -> calendar:datetime().
%% @doc Convert an ISO 8601 formatted string to a
parse(Bin) when is_binary(Bin) ->
    parse(binary_to_list(Bin));
parse(Str) ->
    {{Date, {H, M, S}}, Subsecond} = year(Str, []),
    {Date, {H, M, S + round(Subsecond)}}.

-spec parse_exact (string()) -> calendar:datetime().
%% @doc Convert an ISO 8601 formatted string to a `{date(), time()}'
%% tuple with seconds precision to 3 decimal palces
parse_exact(Bin) when is_binary(Bin) ->
    parse_exact(binary_to_list(Bin));
parse_exact(Str) ->
    {{Date, {H, M, S}}, SecondsDecimal} = year(Str, []),
    {Date, {H, M, S + SecondsDecimal}}.

%% Private functions

year([Y1,Y2,Y3,Y4|Rest], Acc) ->
    acc([Y1,Y2,Y3,Y4], Rest, year, Acc, fun month_or_week/2);
year(_, _) ->
    error(badarg).

month_or_week([], Acc) ->
    datetime(Acc);
month_or_week([$-,$W,W1,W2|Rest], Acc) ->
    acc([W1,W2], Rest, week, Acc, fun week_day/2);
month_or_week([$-,D1,D2,D3], Acc) ->
    %% ordinal date, no time
    io:format("Ordinal date, no time!~n"),
    acc_ordinal_date(D1, D2, D3, [], Acc, fun hour/2);
month_or_week([$-,D1,D2,D3,$T|Rest], Acc) ->
    %% ordinal date with time
    io:format("Ordinal date, time is ~p!~n", [Rest]),
    acc_ordinal_date(D1, D2, D3, [$T|Rest], Acc, fun hour/2);
month_or_week([$-,M1,M2|Rest], Acc) ->
    acc([M1,M2], Rest, month, Acc, fun month_day/2);
month_or_week([$W,W1,W2|Rest], Acc) ->
    acc([W1,W2], Rest, week, Acc, fun week_day_no_hyphen/2);
month_or_week([M1,M2|Rest], Acc) ->
    acc([M1,M2], Rest, month, Acc, fun month_day_no_hyphen/2);
month_or_week(_, _) ->
    error(badarg).

week_day([], Acc) ->
    datetime(Acc);
week_day([$-,D|Rest], Acc) ->
    acc([D], Rest, week_day, Acc, fun hour/2);
week_day(_, _) ->
    error(badarg).

week_day_no_hyphen([], Acc) ->
    datetime(Acc);
week_day_no_hyphen([D|Rest], Acc) ->
    acc([D], Rest, week_day, Acc, fun hour/2);
week_day_no_hyphen(_, _) ->
    error(badarg).

month_day([], Acc) ->
    datetime(Acc);
month_day([$-,D1,D2|Rest], Acc) ->
    acc([D1,D2], Rest, month_day, Acc, fun hour/2);
month_day(_, _) ->
    error(badarg).

month_day_no_hyphen([], _) ->
    error(badarg); % omission of day disallowed by spec in this case
month_day_no_hyphen([D1,D2|Rest], Acc) ->
    acc([D1,D2], Rest, month_day, Acc, fun hour/2);
month_day_no_hyphen(_, _) ->
    error(badarg).

hour([], Acc) ->
    datetime(Acc);
hour([$T,H1,H2,$.|Rest], Acc) ->
    acc([H1,H2], Rest, hour, Acc, fun hour_decimal/2);
hour([$T,H1,H2,$,|Rest], Acc) ->
    acc([H1,H2], Rest, hour, Acc, fun hour_decimal/2);
hour([$T,H1,H2|Rest], Acc) ->
    acc([H1,H2], Rest, hour, Acc, fun minute/2);
hour(_, _) ->
    error(badarg).

hour_decimal(Str, Acc) ->
    decimal(Str, Acc, hour_decimal).

minute([], Acc) ->
    datetime(Acc);
minute([$:,M1,M2,$.|Rest], Acc) ->
    acc([M1,M2], Rest, minute, Acc, fun minute_decimal/2);
minute([$:,M1,M2,$,|Rest], Acc) ->
    acc([M1,M2], Rest, minute, Acc, fun minute_decimal/2);
minute([$:,M1,M2|Rest], Acc) ->
    acc([M1,M2], Rest, minute, Acc, fun second/2);
minute([M1,M2,$.|Rest], Acc) ->
    acc([M1,M2], Rest, minute, Acc, fun minute_decimal/2);
minute([M1,M2,$,|Rest], Acc) ->
    acc([M1,M2], Rest, minute, Acc, fun minute_decimal/2);
minute([M1,M2|Rest], Acc) ->
    acc([M1,M2], Rest, minute, Acc, fun second_no_colon/2);
minute(_, _) ->
    error(badarg).

minute_decimal(Str, Acc) ->
    decimal(Str, Acc, minute_decimal).

second([], Acc) ->
    datetime(Acc);
second([$:,S1,S2,$.|Rest], Acc) ->
    acc([S1,S2], Rest, second, Acc, fun second_decimal/2);
second([$:,S1,S2,$,|Rest], Acc) ->
    acc([S1,S2], Rest, second, Acc, fun second_decimal/2);
second([$:,S1,S2|Rest], Acc) ->
    acc([S1,S2], Rest, second, Acc, fun offset_hour/2);
second(_, _) ->
    error(badarg).

second_no_colon([], Acc) ->
    datetime(Acc);
second_no_colon([S1,S2,$.|Rest], Acc) ->
    acc([S1,S2], Rest, second, Acc, fun second_decimal/2);
second_no_colon([S1,S2,$,|Rest], Acc) ->
    acc([S1,S2], Rest, second, Acc, fun second_decimal/2);
second_no_colon([S1,S2|Rest], Acc) ->
    acc([S1,S2], Rest, second, Acc, fun offset_hour/2);
second_no_colon(_, _) ->
    error(badarg).

second_decimal(Str, Acc) ->
    decimal(Str, Acc, second_decimal).

decimal([], _, _) ->
    error(badarg);
decimal(Str, Acc, Key) ->
    F = fun(X) when is_integer(X), X >= $0, X =< $9 ->
                true;
           (_) ->
                false
        end,
    {Parts, Rest} = lists:splitwith(F, Str),
    acc_float([$0,$.|Parts], Rest, Key, Acc, fun offset_hour/2).

offset_hour([], Acc) ->
    datetime(Acc);
offset_hour([$Z], Acc) ->
    datetime(Acc);
offset_hour([$+,H1,H2|Rest], Acc) ->
    acc([H1,H2], Rest, offset_hour, Acc, fun offset_minute/2);
offset_hour([$-,H1,H2|Rest], Acc) ->
    acc([H1,H2], Rest, offset_hour, [{offset_sign, -1}|Acc], fun offset_minute/2);
offset_hour(_, _) ->
    error(badarg).

offset_minute([], Acc) ->
    datetime(Acc);
offset_minute([$:,M1,M2], Acc) ->
    acc([M1,M2], [], offset_minute, Acc, fun datetime/2);
offset_minute([M1,M2], Acc) ->
    acc([M1,M2], [], offset_minute, Acc, fun datetime/2);
offset_minute(_, _) ->
    error(badarg).

acc(IntStr, Rest, Key, Acc, NextF) ->
    Acc1 = [{Key, list_to_integer(IntStr)}|Acc],
    NextF(Rest, Acc1).

acc_float(FloatStr, Rest, Key, Acc, NextF) ->
    Acc1 = [{Key, list_to_float(FloatStr)}|Acc],
    NextF(Rest, Acc1).

acc_ordinal_date(D1, D2, D3, Rest, Acc, NextF) ->
    Days = list_to_integer([D1, D2, D3]),
    Days > 0 orelse error(badarg),
    Year = ?V(year, Acc),
    Year =/= undefined orelse error(badarg),
    DaysInMonths = days_in_months_for_year(Year),
    { Month, Day } = unpack_ordinal_date(Days, DaysInMonths),
    Acc1 = [{ month, Month }, { month_day, Day }|Acc],
    NextF(Rest, Acc1).

unpack_ordinal_date(Days, DaysInMonths) -> unpack_ordinal_date(1, Days, DaysInMonths).
unpack_ordinal_date(_Month, _Days, []) -> error(badarg), { 0, 0 };
unpack_ordinal_date(_Month, Days, _DaysInMonths) when Days < 0 -> error(badarg), { 0, 0 };
unpack_ordinal_date(Month, Days, [DaysThisMonth|DaysInMonths]) ->
    case Days > DaysThisMonth of
        true -> unpack_ordinal_date(Month + 1, Days - DaysThisMonth, DaysInMonths);
        _ -> { Month, Days }
    end.

days_in_months_for_year(Year) ->
    case is_leap_year(Year) of
        true -> [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
        false -> [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    end.

is_leap_year(Year) ->
    case Year rem 100 of
         0 -> Year rem 400 =:= 0;
         _ ->  Year rem 4 =:= 0
    end.

add_decimal(Datetime, Plist) ->
    HDecimal = ?V(hour_decimal, Plist, 0.0),
    MDecimal = ?V(minute_decimal, Plist, 0.0),
    apply_offset(Datetime, HDecimal, MDecimal, 0.0).

datetime(Plist) ->
    {Date, WeekOffsetH} = make_date(Plist),
    Time = {?V(hour, Plist, 0), ?V(minute, Plist, 0), ?V(second, Plist, 0)},
    Datetime = add_decimal({Date, Time}, Plist),
    OffsetSign = ?V(offset_sign, Plist, 1),
    OffsetH = -1 * OffsetSign * ?V(offset_hour, Plist, 0),
    OffsetM = -1 * OffsetSign * ?V(offset_minute, Plist, 0),
    { apply_offset(Datetime, WeekOffsetH+OffsetH, OffsetM, 0), ?V(second_decimal, Plist, 0.0) }.


datetime(_, Plist) ->
    datetime(Plist).

-spec make_date (datetime_plist())
                -> {Date::calendar:date(), WeekOffsetH::non_neg_integer()}.
%% @doc Return a `tuple' containing a date and, if the date is in week format,
%% an offset in hours that can be applied to the date to adjust it to midnight
%% of the day specified. If month format is used, the offset will be zero.
make_date(Plist) ->
    Year = ?V(year, Plist),
    Year =/= undefined orelse error(badarg),
    make_date(Year, ?V(month, Plist, 1), ?V(week, Plist), Plist).

-spec make_date (non_neg_integer(),
                 maybe(pos_integer()),
                 maybe(pos_integer()),
                 datetime_plist())
                -> {calendar:date(), non_neg_integer()}.
%% @doc Return a `tuple' containing a date and - if the date is in week format
%% (i.e., `Month' is undefined, `Week' is not) - an offset in hours that can be
%% applied to the date to adjust it to midnight of the day specified. If month
%% format is used (i.e., `Week' is undefined, `Month' is not), the offset will
%% be zero.
make_date(Year, Month, undefined, Plist) ->
    Date = {Year, Month, ?V(month_day, Plist, 1)},
    {Date, 0};
make_date(Year, _, Week, Plist) ->
    Weekday = ?V(week_day, Plist, 1),
    OffsetH = ((Week-1)*7 + (Weekday-1))*24, % week/weekday offset in hours
    {date_at_w01_1(Year), OffsetH}.

-spec date_at_w01_1(pos_integer()) -> calendar:date().
%% @doc Calculate the `calendar:date()' at ISO week 1, day 1 in the supplied
%% year.
date_at_w01_1(Year) ->
    case calendar:day_of_the_week({Year,1,1}) of
        1 -> {Year, 1, 1};
        2 -> {Year-1, 12, 31};
        3 -> {Year-1, 12, 30};
        4 -> {Year-1, 12, 29};
        5 -> {Year, 1, 4};
        6 -> {Year, 1, 3};
        7 -> {Year, 1, 2}
    end.

-spec apply_offset (calendar:datetime(), number(), number(), number())
                   -> calendar:datetime().
%% @doc Add the specified number of hours, minutes and seconds to `Datetime'.
apply_offset(Datetime, H, M, S) ->
    OffsetS = S + (60 * (M + (60 * H))),
    Gs = round(OffsetS) + calendar:datetime_to_gregorian_seconds(Datetime),
    calendar:gregorian_seconds_to_datetime(Gs).

© 著作权归作者所有

共有 人打赏支持
nao

nao

粉丝 28
博文 151
码字总数 107499
作品 0
徐汇
时间戳转换 时间函数time(); date();

必需。规定输出日期字符串的格式。可使用下列字符: d - 一个月中的第几天(从 01 到 31) D - 星期几的文本表示(用三个字母表示) j - 一个月中的第几天,不带前导零(1 到 31) l('L' 的...

阿锋zxf
06/27
0
0
FreeMarker日期内建函数

date, time, datetime (当用于日期/时间/日期-时间值时) 这些内建函数用来指定日期变量中的哪些部分被使用: :仅日期部分,没有一天当中的时间部分。 :仅一天当中的时间部分,没有日期部分...

楠木楠
2016/11/27
26
0
DPDateExtension

DP_DateExtensions库继承了JavaScript的Date对象,并添加了一些新特性和功能。 添加了富特性的timeFormat()以及dateFormat()方法,允许你对时间和日期值进行微操 通过add()和diff()方法轻松操...

匿名
2012/03/13
546
0
Python时间日期库--Arrow

Arrow是一个专门处理时间和日期的轻量级Python库,它提供了一种合理、智能的方式来创建、操作、格式化、转换时间和日期。其设计灵感主要来源于moment.js。 为什么要设计Arrow? 从可用性角度...

欢哥
2013/06/05
1K
1
关于Logstash中grok插件的正则表达式例子

关于Logstash中grok插件的正则表达式例子 一、前言 近期需要对产生的日志进行采集,问了下度娘,业内最著名的解决方案非(, , )莫属。 负责采集日志,负责存储、索引日志,则负责通过Web形式展...

xianglc5474
2016/12/16
92
0
PHP date 格式化一个本地时间/日期

date(PHP 4, PHP 5) date — 格式化一个本地时间/日期 说明string date ( string $format [, int $timestamp ] )返回将整数 timestamp 按照给定的格式字串而产生的字符串。如果没有给出时间...

Jack088
2016/09/09
25
0
新款时间日期API已上线

历史 早期,Java 对时间和日期的使用往往重度依赖 java.util.Date和java.util.Calendar。 可惜的是,这2个api 本身不够健壮,有类似线程不安全等诸多问题,于是乎2000年左右,市面上出现了很...

Garrry
2016/01/18
126
0
MySQL · 特性分析 · 5.7 error log 时区和系统时区不同

问题描述 现象 5.6 和 5.7 时区设置相同,select now()也显示当前时间 5.7 error log 中时间和当前时间差8小时 问题分析 5.6 写 error log 函数如下 取时间的函数是localtimer(&skr, &tmtmp...

阿里云RDS-数据库内核组
2017/01/10
0
0
PostgreSQL 【常用数据类型】

一、数值类型: 下面是PostgreSQL所支持的数值类型的列表和简单说明: 名字 存储空间 描述 范围 smallint 2 字节 小范围整数 -32768 到 +32767 integer 4 字节 常用的整数 -2147483648 到 +2...

SibylY
2015/11/20
0
0
PostgreSQL学习手册(四) 常用数据类型

一、数值类型: 下面是PostgreSQL所支持的数值类型的列表和简单说明: 1. 整数类型: 类型smallint、integer和bigint存储各种范围的全部是数字的数,也就是没有小数部分的数字。试图存储超出...

长平狐
2012/08/27
117
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

SpringBoot | 第十章:Swagger2的集成和使用

前言 前一章节介绍了mybatisPlus的集成和简单使用,本章节开始接着上一章节的用户表,进行Swagger2的集成。现在都奉行前后端分离开发和微服务大行其道,分微服务及前后端分离后,前后端开发的...

oKong
今天
9
0
Python 最小二乘法 拟合 二次曲线

Python 二次拟合 随机生成数据,并且加上噪声干扰 构造需要拟合的函数形式,使用最小二乘法进行拟合 输出拟合后的参数 将拟合后的函数与原始数据绘图后进行对比 import numpy as npimport...

阿豪boy
今天
4
0
云拿 无人便利店

附近(上海市-航南路)开了家无人便利店.特意进去体验了一下.下面把自己看到的跟大家分享下. 经得现场工作人员同意后拍了几张照片.从外面看是这样.店门口的指导里强调:不要一次扫码多个人进入....

周翔
昨天
1
0
Java设计模式学习之工厂模式

在Java(或者叫做面向对象语言)的世界中,工厂模式被广泛应用于项目中,也许你并没有听说过,不过也许你已经在使用了。 简单来说,工厂模式的出现源于增加程序序的可扩展性,降低耦合度。之...

路小磊
昨天
176
1
npm profile 新功能介绍

转载地址 npm profile 新功能介绍 npm新版本新推来一个功能,npm profile,这个可以更改自己简介信息的命令,以后可以不用去登录网站来修改自己的简介了 具体的这个功能的支持大概是在6这个版...

durban
昨天
1
0
Serial2Ethernet Bi-redirection

Serial Tool Serial Tool is a utility for developing serial communications, custom protocols or device testing. You can set up bytes to send accordingly to your protocol and save......

zungyiu
昨天
1
0
python里求解物理学上的双弹簧质能系统

物理的模型如下: 在这个系统里有两个物体,它们的质量分别是m1和m2,被两个弹簧连接在一起,伸缩系统为k1和k2,左端固定。假定没有外力时,两个弹簧的长度为L1和L2。 由于两物体有重力,那么...

wangxuwei
昨天
0
0
apolloxlua 介绍

##项目介绍 apolloxlua 目前支持javascript到lua的翻译。可以在openresty和luajit里使用。这个工具分为两种模式, 一种是web模式,可以通过网页使用。另外一种是tool模式, 通常作为大规模翻...

钟元OSS
昨天
2
0
Mybatis入门

简介: 定义:Mybatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。 途径:MyBatis通过XML文件或者注解的形式配置映射,实现数据库查询。 特性:动态SQL语句。 文件结构:Mybat...

霍淇滨
昨天
2
0
开发技术瓶颈期,如何突破

前言 读书、学习的那些事情,以前我也陆续叨叨了不少,但总觉得 “学习方法” 就是一个永远在路上的话题。个人的能力、经验积累与习惯方法不尽相同,而且一篇文章甚至一本书都很难将学习方法...

_小迷糊
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部