当前位置:K88软件开发文章中心编程语言非主流编程语言Julia → 文章内容

Julia 日期和时间

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-15 16:28:22

tes.dayofquarter(t) 31dayname 和 monthname 可以传入可选参数 locale 来显示 julia> const french_daysofweek = [1=>"Lundi",2=>"Mardi",3=>"Mercredi",4=>"Jeudi",5=>"Vendredi",6=>"Samedi",7=>"Dimanche"]; # Load the mapping into the Dates module under locale name "french" julia> Dates.VALUETODAYOFWEEK["french"] = french_daysofweek; julia> Dates.dayname(t;locale="french") "Vendredi"monthname 与之类似的, 这时, Dates.VALUETOMONTH 需要加载 locale=>Dict{Int, UTF8String}.时间间隔算术运算在使用任何一门编程语言/时间日期框架前, 最好了解下时间间隔是怎么处理的, 因为有些地方需要特殊的技巧.Dates 模块的工作方式是这样的, 在做 period 算术运算时, 每次都做尽量小的改动. 这种方式被称之为 日历 算术, 或者就是平时日常交流中惯用的方式. 这些到底是什么? 举个经典的例子: 2014 年 1 月 31 号加一月. 答案是什么? JavaScript 会得出 3月3号 (假设31天). PHP 会得到 3月2号 <http://stackoverflow.com/questions/5760262/php-adding-months-to-a-date-while-not-exceeding-the-last-day-of-the-month>_ (假设30天). 事实上, 这个问题没有正确答案. Dates 模块会给出 2月28号的答案. 它是怎么得出的? 试想下赌场的 7-7-7 赌博游戏.设想下, 赌博机的槽不是 7-7-7, 而是年-月-日, 或者在我们的例子中, 2014-01-31. 当你想要在这个日期上增加一个月时, 对应于月份的那个槽会增加1, 所以现在是 2014-02-31, 然后检查年-月-日中的日是否超过了这个月最大的合法的数字 (28). 这种方法有什么后果呢? 我们继续加上一个月, 2014-02-28 + Month(1) == 2014-03-28. 什么? 你是不是期望结果是3月的最后一天? 抱歉, 不是的, 想一下 7-7-7. 因为要改变尽量少的槽, 所以我们在月份上加1, 2014-03-28, 然后就没有然后了, 因为这是个合法的日期. 然而, 如果我们在原来的日期(2014-01-31)上加上2个月, 我们会得到预想中的 2014-03-31. 这种方式带来的另一个问题是损失了可交换性, 如果强制加法的顺序的话 (也就是说,用不用的顺序相加会得到不同的结果). 例如 :: julia> (Date(2014,1,29)+Dates.Day(1)) + Dates.Month(1) 2014-02-28 julia> (Date(2014,1,29)+Dates.Month(1)) + Dates.Day(1) 2014-03-01这是怎么回事? 第一个例子中, 我们往1月29号加上一天, 得到 2014-01-30; 然后加上一月, 得到 2014-02-30, 然后被调整到 2014-02-28. 在第二个例子中, 我们 先 加一个月, 得到 2014-02-29, 然后被调整到 2014-02-28, 然后 加一天, 得到 2014-03-01. 在处理这种问题时的一个设计原则是, 如果有多个时间间隔, 操作的顺序是按照间隔的 类型 排列的, 而不是按照他们的值大小或者出现顺序; 这就是说, 第一个加的是 Year, 然后是 Month, 然后是 Week, 等等. 所以下面的例子 是 符合可交换性的 :: julia> Date(2014,1,29) + Dates.Day(1) + Dates.Month(1) 2014-03-01 julia> Date(2014,1,29) + Dates.Month(1) + Dates.Day(1) 2014-03-01很麻烦? 也许吧. 一个 Dates 的初级用户该怎么办呢? 最基本的是要清楚, 当操作月份时, 如果强制指明操作的顺序, 可能会产生意想不到的结果, 其他的就没什么了. 幸运的是, 这基本就是所有的特殊情况了 (UT 时间已经免除了夏令时, 闰秒之类的麻烦).调整函数时间间隔的算术运算是很方便, 但同时, 有些时间的操作是基于 日历 或者 时间 本身的, 而不是一个固定的时间间隔. 例如假期的计算, 诸如 "纪念日 = 五月的最后一个周一", 或者 "感恩节 = 十一月的第四个周四". 这些时间的计算牵涉到基于日历的规则, 例如某个月的第一天或者最后一天, 下一个周四, 或者第一个和第三个周三, 等等.Dates 模块提供几个了 调整 函数, 这样可以简单简洁的描述时间规则. 第一组是关于周, 月, 季度, 年的第一和最后一个元素. 函数参数为 TimeType, 然后按照规则返回或者 调整 到正确的日期。 # 调整时间到相应的周一 julia> Dates.firstdayofweek(Date(2014,7,16)) 2014-07-14 # 调整时间到这个月的最后一天 julia> Dates.lastdayofmonth(Date(2014,7,16)) 2014-07-31 # 调整时间到这个季度的最后一天 julia> Dates.lastdayofquarter(Date(2014,7,16)) 2014-09-30接下来一组高阶函数, tofirst, tolast, tonext, and toprev, 第一个参数为 DateFunction, 第二个参数 TimeType 作为起点日期. 一个 DateFunction 类型的变量是一个函数, 通常是匿名函数, 这个函数接受 TimeType 作为输入, 返回 Bool, true 来表示是否满足特定的条件. 例如 :: julia> istuesday = x->Dates.dayofweek(x) == Dates.Tuesday # 如果是周二, 返回 true (anonymous function) julia> Dates.tonext(istuesday, Date(2014,7,13)) # 2014-07-13 is a 是周日 2014-07-15 # 同时也额外提供了一些函数, 使得对星期几之类的操作更加方便 julia> Dates.tonext(Date(2014,7,13), Dates.Tuesday) 2014-07-15如果是复杂的时间表达式, 使用 do-block 会很方便: julia> Dates.tonext(Date(2014,7,13)) do x # 如果是十一月的第四个星期四, 返回 true (感恩节) Dates.dayofweek(x) == Dates.Thursday && Dates.dayofweekofmonth(x) == 4 && Dates.month(x) == Dates.November end 2014-11-27类似的, tofirst 和 tolast 第一个参数为 DateFunction, 但是默认的调整范围位当月, 或者可以用关键字参数指明调整范围为当年 : julia> Dates.tofirst(istuesday, Date(2014,7,13)) # 默认位当月 2014-07-01 julia> Dates.tofirst(istuesday, Date(2014,7,13); of=Dates.Year) 2014-01-07 julia> Dates.tolast(istuesday, Date(2014,7,13)) 2014-07-29 julia> Dates.tolast(istuesday, Date(2014,7,13); of=Dates.Year) 2014-12-30最后一个函数为 recur. recur 函数是向量化的调整过程, 输入为起始和结束日期 (或者指明 StepRange), 加上一个 DateFunction 来判断某个日期是否应该返回. 这种情况下, DateFunction 又被经常称为 "包括" 函数, 因为它指明了 (通过返回 true) 某个日期是否应该出现在返回的日期数组中。 # 匹兹堡大街清理日

上一页  [1] [2] [3]  下一页


Julia 日期和时间