aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/eventlog/dumper/common.cpp
blob: eebe3b6ee3306b865e48ff126cd550d1866e2e99 (plain) (blame)
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
#include "common.h"

#include <contrib/libs/re2/re2/re2.h>

#include <util/datetime/base.h>
#include <util/datetime/parser.h>
#include <util/string/cast.h>

static time_t RecentTime(int h, int m, int s) {
    time_t now = time(nullptr);
    tm tmTmp;
    localtime_r(&now, &tmTmp);
    tmTmp.tm_hour = h;
    tmTmp.tm_min = m;
    tmTmp.tm_sec = s;
    time_t today = mktime(&tmTmp);
    tmTmp.tm_mday -= 1;
    time_t yesterday = mktime(&tmTmp);
    return today <= now ? today : yesterday;
}

static bool ParseRecentTime(const TString& str, time_t& result) {
    RE2 RecentTimePattern("(\\d{1,2}):(\\d{2})(?::(\\d{2}))?");
    re2::StringPiece hStr, mStr, sStr;
    if (!RE2::FullMatch({str.data(), str.size()}, RecentTimePattern, &hStr, &mStr, &sStr)) {
        return false;
    }
    int h = FromString<int>(hStr.data(), hStr.length());
    int m = FromString<int>(mStr.data(), mStr.length());
    int s = FromString<int>(sStr.data(), sStr.length(), 0);
    if (h > 23 || m > 59 || s > 59) {
        return false;
    }
    result = RecentTime(h, m, s);
    return true;
}

namespace {
    class TDefaultOffset8601Parser: public TIso8601DateTimeParser {
    public:
        TDefaultOffset8601Parser(int offsetHours) {
            DateTimeFields.ZoneOffsetMinutes = offsetHours * 60;
        }
    };
} // namespace

static bool ParseISO8601DateTimeWithDefaultOffset(TStringBuf str, int offsetHours, time_t& result) {
    TDefaultOffset8601Parser parser{offsetHours};

    if (!parser.ParsePart(str.data(), str.size())) {
        return false;
    }

    const TInstant instant = parser.GetResult(TInstant::Max());
    if (instant == TInstant::Max()) {
        return false;
    }

    result = instant.TimeT();
    return true;
}

ui64 ParseTime(const TString& str, ui64 defValue, int offset) {
    if (!str) {
        return defValue;
    }

    time_t utcTime;

    if (ParseISO8601DateTimeWithDefaultOffset(str, offset, utcTime)) {
        return (ui64)utcTime * 1000000;
    }

    if (ParseRecentTime(str, utcTime)) {
        return (ui64)utcTime * 1000000;
    }

    // if conversion fails, TryFromString leaves defValue unchanged
    TryFromString<ui64>(str, defValue);
    return defValue;
}