Add tags

Add tags to the following comment
明治元年~明治5年の範囲で太陰暦にも対応しました。
(黄道の計算などはしておらず、5年分のテーブルを持っているだけです。)
漢字での出力に対応していますが、utf-8専用です。

% ./dk122 1868/12/2
明治元年10月19日
% ./dk122 1926/12/24
大正15年12月24日
% ./dk122 2007/12/01
平成19年12月1日
% ./dk122 1926/12/25
大正15年12月25日  昭和元年12月25日
% ./dk122 1868/1/2
範囲外
% ./dk122 1868/100/2
範囲外

【追加テスト】
% ./dk122 1873/1/1
明治6年1月1日
% ./dk122 1872/12/31
明治5年12月2日
% ./dk122 1868/10/23
明治元年9月8日
% ./dk122 1870/10/25
明治3年10月1日
% ./dk122 1870/11/23
明治3年閏10月1日
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
open String
open Printf

let meiji   = "\xE6\x98\x8E\xE6\xB2\xBB"
let taishou = "\xE5\xA4\xA7\xE6\xAD\xA3"
let showa   = "\xE6\x98\xAD\xE5\x92\x8C"
let heisei  = "\xE5\xB9\xB3\xE6\x88\x90"
let gan     = "\xE5\x85\x83"
let nen     = "\xE5\xB9\xB4"
let gatsu   = "\xE6\x9C\x88"
let nichi   = "\xE6\x97\xA5"
let uruu    = "\xE9\x96\x8F"

        (* M1   Meiji 2      Meiji 3       Meiji 4      Meiji 5    *)
let tab = "9009 000990990900 900909090jj09 009009090990 909009009092"

let errmsg = "\xE7\xAF\x84\xE5\x9B\xB2\xE5\xA4\x96"
let mtab = [| 0; 31; 29; 31; 30; 31; 30; 31; 31; 30; 31; 30; 31 |]

let prt1 era y m d =
    let ystr = if y = 1 then gan else string_of_int y in
    let leap = if m mod 2 = 1 then uruu else "" in
    sprintf "%s%s%s%s%d%s%d%s" era ystr nen leap (m/2) gatsu d nichi

let prt2 era1 y1 era2 y2 m d = sprintf "%s  %s" (prt1 era1 y1 m d) (prt1 era2 y2 m d)

let dec i (year, month) = if month - 2 >= i then year    , month - i
                                            else year - 1, month - i + 24

let rec search target i r (year, month as date) =
    if r < target then year, month, target - r
        else let r', d' = match tab.[i] with
            | '0' -> 30, 2 | '9' -> 29, 2 | '2' -> 2, 2 | 'j' -> 29, 1 | _ -> 0, 0 in
            search target (i - 1) (r - r') (dec d' date)

let taiin year month day =
    let y, m = if month < 3 then year - 1, month + 12 else year, month in
    let w = y * 365 + y / 4 - y / 100 + y / 400 + (m + 1) * 306 / 10 + day - 428 in
    let y, m, d = search w ((length tab) - 1) 683734 (5, 26) in prt1 meiji y m d

let rec split s sep =
    try
        let i = index s sep in
        sub s 0 i ::  split (sub s (i+1) ((length s) - i - 1)) sep
    with Not_found -> [ s ]

let check year month day =
    if year < 1868 || month < 1 || month > 12 || day < 1 then false else
        match year mod 400, year mod 100, year mod 4, month, day with
        | 0, _, _, 2, x when x <= 29       -> true
        | _, 0, _, 2, x when x >= 29       -> false
        | _, _, 0, 2, x when x <= 29       -> true
        | _, _, _, i, x when x <= mtab.(i) -> true
        | _, _, _, _, _                    -> false

let conv2 year month day =
    match year * 10000 + month * 100 + day with
    | ymd when ymd > 19890107 -> prt1 heisei  (year - 1988) (month * 2) day
    | ymd when ymd > 19261225 -> prt1 showa   (year - 1925) (month * 2) day
    | 19261225                -> prt2 taishou 15 showa 1    (month * 2) day
    | ymd when ymd > 19120730 -> prt1 taishou (year - 1911) (month * 2) day
    | 19120730                -> prt2 meiji 45 taishou 1    (month * 2) day
    | ymd when ymd > 18730100 -> prt1 meiji   (year - 1867) (month * 2) day
    | ymd when ymd > 18681022 -> taiin year month day
    | _                       -> errmsg

let conv s = match split s '/' with
    | y :: m :: d :: [] ->
        let f x = try int_of_string x with _ -> 0 in
        let year, month, day = f y, f m, f d in
        if check year month day then conv2 year month day else errmsg
    | _ -> errmsg

let _ = Printf.printf "%s\n" (conv Sys.argv.(1))

Add tags

The input will be splited to tags with space.

Index

Feed

Other

Link

Pathtraq

loading...