File: moment_parse.c

package info (click to toggle)
libtime-moment-perl 0.41-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 1,024 kB
  • ctags: 1,354
  • sloc: perl: 6,312; ansic: 2,936; makefile: 3
file content (106 lines) | stat: -rw-r--r-- 2,231 bytes parent folder | download | duplicates (2)
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "moment.h"
#include "dt_core.h"
#include "dt_parse_iso.h"

static int
parse_string_lenient(const char *str, size_t len, int64_t *sp, IV *np, IV *op) {
    size_t n;
    dt_t dt;
    char c;
    int sod, nanosecond, offset;

    n = dt_parse_iso_date(str, len, &dt);
    if (!n || n == len)
        return 1;

    c = str[n++];
    if (!(c == 'T' || c == 't' || c == ' '))
        return 1;

    str += n;
    len -= n;

    n = dt_parse_iso_time(str, len, &sod, &nanosecond);
    if (!n || n == len)
        return 1;

    if (str[n] == ' ')
        n++;

    str += n;
    len -= n;

    n = dt_parse_iso_zone_lenient(str, len, &offset);
    if (!n || n != len)
        return 1;

    *sp = ((int64_t)dt_rdn(dt) - 719163) * 86400 + sod - offset * 60;
    *np = nanosecond;
    *op = offset;
    return 0;
}

static int
parse_string_strict(const char *str, size_t len, int64_t *sp, IV *np, IV *op) {
    size_t n;
    dt_t dt;
    int sod, nanosecond, offset;
    bool extended;

    n = dt_parse_iso_date(str, len, &dt);
    if (!n || n == len)
        return 1;

   /*
    * 0123456789
    * 2012-12-14
    */
    extended = str[4] == '-';
    if (str[n++] != 'T')
        return 1;

    str += n;
    len -= n;

    if (extended)
        n = dt_parse_iso_time_extended(str, len, &sod, &nanosecond);
    else
        n = dt_parse_iso_time_basic(str, len, &sod, &nanosecond);

    if (!n || n == len)
        return 1;

    str += n;
    len -= n;

    if (extended)
        n = dt_parse_iso_zone_extended(str, len, &offset);
    else
        n = dt_parse_iso_zone_basic(str, len, &offset);

    if (!n || n != len)
        return 1;

    *sp = ((int64_t)dt_rdn(dt) - 719163) * 86400 + sod - offset * 60;
    *np = nanosecond;
    *op = offset;
    return 0;
}

moment_t
THX_moment_from_string(pTHX_ const char *str, STRLEN len, bool lenient) {
    int ret;
    int64_t seconds;
    IV nanosecond, offset;

    if (lenient)
        ret = parse_string_lenient(str, len, &seconds, &nanosecond, &offset);
    else
        ret = parse_string_strict(str, len, &seconds, &nanosecond, &offset);

    if (ret != 0)
        croak("Could not parse the given string");

    return moment_from_epoch(seconds, nanosecond, offset);
}