Coverage Report

Created: 2025-06-13 06:34

/src/icu/icu4c/source/i18n/cecal.cpp
Line
Count
Source (jump to first uncovered line)
1
// © 2016 and later: Unicode, Inc. and others.
2
// License & terms of use: http://www.unicode.org/copyright.html
3
/*
4
*******************************************************************************
5
* Copyright (C) 2003 - 2009, International Business Machines Corporation and  *
6
* others. All Rights Reserved.                                                *
7
*******************************************************************************
8
*/
9
10
#include "unicode/utypes.h"
11
12
#if !UCONFIG_NO_FORMATTING
13
14
#include "cecal.h"
15
#include "gregoimp.h"   //Math
16
#include "cstring.h"
17
18
U_NAMESPACE_BEGIN
19
20
static const int32_t LIMITS[UCAL_FIELD_COUNT][4] = {
21
    // Minimum  Greatest    Least  Maximum
22
    //           Minimum  Maximum
23
    {        0,        0,        1,        1}, // ERA
24
    {        1,        1,  5000000,  5000000}, // YEAR
25
    {        0,        0,       12,       12}, // MONTH
26
    {        1,        1,       52,       53}, // WEEK_OF_YEAR
27
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // WEEK_OF_MONTH
28
    {        1,        1,        5,       30}, // DAY_OF_MONTH
29
    {        1,        1,      365,      366}, // DAY_OF_YEAR
30
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DAY_OF_WEEK
31
    {       -1,       -1,        1,        5}, // DAY_OF_WEEK_IN_MONTH
32
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // AM_PM
33
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR
34
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR_OF_DAY
35
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MINUTE
36
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // SECOND
37
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MILLISECOND
38
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // ZONE_OFFSET
39
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DST_OFFSET
40
    { -5000000, -5000000,  5000000,  5000000}, // YEAR_WOY
41
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DOW_LOCAL
42
    { -5000000, -5000000,  5000000,  5000000}, // EXTENDED_YEAR
43
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // JULIAN_DAY
44
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MILLISECONDS_IN_DAY
45
    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // IS_LEAP_MONTH
46
    {        0,        0,       12,       12}, // ORDINAL_MONTH
47
};
48
49
//-------------------------------------------------------------------------
50
// Constructors...
51
//-------------------------------------------------------------------------
52
53
CECalendar::CECalendar(const Locale& aLocale, UErrorCode& success)
54
272
:   Calendar(TimeZone::forLocaleOrDefault(aLocale), aLocale, success)
55
272
{
56
272
}
57
58
CECalendar::CECalendar (const CECalendar& other) 
59
4.79k
:   Calendar(other)
60
4.79k
{
61
4.79k
}
62
63
CECalendar::~CECalendar()
64
4.96k
{
65
4.96k
}
66
67
//-------------------------------------------------------------------------
68
// Calendar framework
69
//-------------------------------------------------------------------------
70
71
int64_t
72
CECalendar::handleComputeMonthStart(int32_t eyear,int32_t emonth, UBool /*useMonth*/, UErrorCode& /*status*/) const
73
51.4k
{
74
51.4k
    int64_t year64 = eyear;
75
    // handle month > 12, < 0 (e.g. from add/set)
76
51.4k
    if ( emonth >= 0 ) {
77
50.0k
        year64 += emonth/13;
78
50.0k
        emonth %= 13;
79
50.0k
    } else {
80
1.42k
        ++emonth;
81
1.42k
        year64 += emonth/13 - 1;
82
1.42k
        emonth = emonth%13 + 12;
83
1.42k
    }
84
85
51.4k
    return (
86
51.4k
        getJDEpochOffset()                    // difference from Julian epoch to 1,1,1
87
51.4k
        + 365LL * year64                      // number of days from years
88
51.4k
        + ClockMath::floorDivideInt64(year64, 4LL) // extra day of leap year
89
51.4k
        + 30 * emonth                         // number of days from months (months are 0-based)
90
51.4k
        - 1                                   // number of days for present month (1 based)
91
51.4k
        );
92
51.4k
}
93
94
int32_t
95
CECalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const
96
14.5k
{
97
14.5k
    return LIMITS[field][limitType];
98
14.5k
}
99
100
//-------------------------------------------------------------------------
101
// Calendar system Conversion methods...
102
//-------------------------------------------------------------------------
103
104
namespace {
105
void jdToCE(int32_t julianDay, int32_t jdEpochOffset, int32_t& year, int32_t& month, int32_t& day, int32_t& doy, UErrorCode& status)
106
16.6k
{
107
16.6k
    int32_t c4; // number of 4 year cycle (1461 days)
108
16.6k
    int32_t r4; // remainder of 4 year cycle, always positive
109
110
16.6k
    if (uprv_add32_overflow(julianDay, -jdEpochOffset, &julianDay)) {
111
23
        status = U_ILLEGAL_ARGUMENT_ERROR;
112
23
        return;
113
23
    }
114
16.6k
    c4 = ClockMath::floorDivide(julianDay, 1461, &r4);
115
116
16.6k
    year = 4 * c4 + (r4/365 - r4/1460); // 4 * <number of 4year cycle> + <years within the last cycle>
117
118
16.6k
    doy = (r4 == 1460) ? 365 : (r4 % 365); // days in present year
119
120
16.6k
    month = doy / 30;       // 30 -> Coptic/Ethiopic month length up to 12th month
121
16.6k
    day = (doy % 30) + 1;   // 1-based days in a month
122
16.6k
    doy++;  // 1-based days in a year.
123
16.6k
}
124
}  // namespace
125
126
void
127
CECalendar::handleComputeFields(int32_t julianDay, UErrorCode& status)
128
16.6k
{
129
16.6k
    int32_t eyear, month, day, doy;
130
16.6k
    jdToCE(julianDay, getJDEpochOffset(), eyear, month, day, doy, status);
131
16.6k
    if (U_FAILURE(status)) return;
132
16.6k
    int32_t era = extendedYearToEra(eyear);
133
16.6k
    int32_t year = extendedYearToYear(eyear);
134
135
16.6k
    internalSet(UCAL_EXTENDED_YEAR, eyear);
136
16.6k
    internalSet(UCAL_ERA, era);
137
16.6k
    internalSet(UCAL_YEAR, year);
138
16.6k
    internalSet(UCAL_MONTH, month);
139
16.6k
    internalSet(UCAL_ORDINAL_MONTH, month);
140
16.6k
    internalSet(UCAL_DATE, day);
141
16.6k
    internalSet(UCAL_DAY_OF_YEAR, doy);
142
16.6k
}
143
144
static const char* kMonthCode13 = "M13";
145
146
0
const char* CECalendar::getTemporalMonthCode(UErrorCode& status) const {
147
0
    if (get(UCAL_MONTH, status) == 12) {
148
0
        return kMonthCode13;
149
0
    }
150
0
    return Calendar::getTemporalMonthCode(status);
151
0
}
152
153
void
154
0
CECalendar::setTemporalMonthCode(const char* code, UErrorCode& status) {
155
0
    if (U_FAILURE(status)) {
156
0
        return;
157
0
    }
158
0
    if (uprv_strcmp(code, kMonthCode13) == 0) {
159
0
        set(UCAL_MONTH, 12);
160
0
        set(UCAL_IS_LEAP_MONTH, 0);
161
0
        return;
162
0
    }
163
0
    Calendar::setTemporalMonthCode(code, status);
164
0
}
165
166
U_NAMESPACE_END
167
168
#endif /* #if !UCONFIG_NO_FORMATTING */
169
//eof