zhao
2021-06-04 c7ec496f9e41c2227103b3ef776e4a3f91bce6b2
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
107
108
109
110
111
112
113
114
115
116
117
/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for Additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at
 
       http://www.apache.org/licenses/LICENSE-2.0
 
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */
 
namespace HH.WMS.Utils.NPOI.SS.Formula.Functions
{
    using HH.WMS.Utils.NPOI.SS.Formula.Eval;
    using HH.WMS.Utils.NPOI.SS.UserModel;
    using System;
 
    /**
     * Implementation of Excel functions Date parsing functions:
     *  Date - DAY, MONTH and YEAR
     *  Time - HOUR, MINUTE and SECOND
     */
    public class CalendarFieldFunction : Fixed1ArgFunction
    {
        public const int YEAR_ID = 0x01;
        public const int MONTH_ID = 0x02;
        public const int DAY_OF_MONTH_ID = 0x03;
        public const int HOUR_OF_DAY_ID = 0x04;
        public const int MINUTE_ID = 0x05;
        public const int SECOND_ID = 0x06;
 
        public static Function YEAR = new CalendarFieldFunction(YEAR_ID);
        public static Function MONTH = new CalendarFieldFunction(MONTH_ID);
        public static Function DAY = new CalendarFieldFunction(DAY_OF_MONTH_ID);
        public static Function HOUR = new CalendarFieldFunction(HOUR_OF_DAY_ID);
        public static Function MINUTE = new CalendarFieldFunction(MINUTE_ID);
        public static Function SECOND = new CalendarFieldFunction(SECOND_ID);
 
        private int _dateFieldId;
 
        private CalendarFieldFunction(int dateFieldId)
        {
            _dateFieldId = dateFieldId;
        }
 
        public override ValueEval Evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0)
        {
            double val;
            try
            {
                ValueEval ve = OperandResolver.GetSingleValue(arg0, srcRowIndex, srcColumnIndex);
                val = OperandResolver.CoerceValueToDouble(ve);
            }
            catch (EvaluationException e)
            {
                return e.GetErrorEval();
            }
            if (val < 0)
            {
                return ErrorEval.NUM_ERROR;
            }
            return new NumberEval(GetCalField(val));
        }
 
        private int GetCalField(double serialDate)
        {
            if ((int)serialDate == 0)
            {
                // Special weird case
                // day zero should be 31-Dec-1899,  but Excel seems to think it is 0-Jan-1900
                switch (_dateFieldId)
                {
                    case YEAR_ID: return 1900;
                    case MONTH_ID: return 1;
                    case DAY_OF_MONTH_ID: return 0;
                }
                //throw new InvalidOperationException("bad date field " + _dateFieldId);
            }
            DateTime d = DateUtil.GetJavaDate(serialDate, false); // TODO fix 1900/1904 problem
 
            //Calendar c = new GregorianCalendar();
            //c.setTime(d);
            int result = 0;
            if (_dateFieldId == YEAR_ID)
            {
                result = d.Year;
            }
            else if (_dateFieldId == MONTH_ID)
            {
                result = d.Month;
            }
            else if (_dateFieldId == DAY_OF_MONTH_ID)
            {
                result = d.Day;
            }
            else if (_dateFieldId == HOUR_OF_DAY_ID)
            {
                result = d.Hour;
            }
            else if (_dateFieldId == MINUTE_ID)
            {
                result = d.Minute;
            }
            else if (_dateFieldId == SECOND_ID)
            {
                result = d.Second;
            }
            return result;
        }
    }
}