zhao
2021-07-02 081df17b8cc4a6e7e4f4e1e1887f24810e3ec2f9
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
using System;
using System.Collections.Generic;
using System.Text;
using HH.WMS.Utils.NPOI.SS.Formula.Eval;
using HH.WMS.Utils.NPOI.SS.UserModel;
 
namespace HH.WMS.Utils.NPOI.SS.Formula.Functions
{
    public class Days360 : Var2or3ArgFunction
    {
 
        public override ValueEval Evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1)
        {
            double result;
            try
            {
                double d0 = NumericFunction.SingleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
                double d1 = NumericFunction.SingleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
                result = Evaluate(d0, d1);
            }
            catch (EvaluationException e)
            {
                return e.GetErrorEval();
            }
            return new NumberEval(result);
        }
 
        public override ValueEval Evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, ValueEval arg2)
        {
            double result;
            try
            {
                double d0 = NumericFunction.SingleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
                double d1 = NumericFunction.SingleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
                ValueEval ve = OperandResolver.GetSingleValue(arg2, srcRowIndex, srcColumnIndex);
                bool? method = OperandResolver.CoerceValueToBoolean(ve, false);
                result = Evaluate(d0, d1);
            }
            catch (EvaluationException e)
            {
                return e.GetErrorEval();
            }
            return new NumberEval(result);
        }
        private double Evaluate(double d0, double d1)
        {
            DateTime startingDate = GetStartingDate(d0);
            DateTime endingDate = GetEndingDateAccordingToStartingDate(d1, startingDate);
            long startingDay = startingDate.Month * 30 + startingDate.Day;
            long endingDay = (endingDate.Year - startingDate.Year) * 360
                    + endingDate.Month * 30 + endingDate.Day;
            return endingDay - startingDay;
        }
        private DateTime GetDate(double date)
        {
            return DateUtil.GetJavaDate(date);
        }
        private DateTime GetStartingDate(double date)
        {
            DateTime startingDate = GetDate(date);
            if (IsLastDayOfMonth(startingDate))
            {
                startingDate = new DateTime(startingDate.Year, startingDate.Month, 30, startingDate.Hour, startingDate.Minute, startingDate.Second);
            }
            return startingDate;
        }
        private DateTime GetEndingDateAccordingToStartingDate(double date, DateTime startingDate)
        {
            DateTime endingDate = DateUtil.GetJavaDate(date, false);
            if (IsLastDayOfMonth(endingDate))
            {
                if (startingDate.Day < 30)
                {
                    endingDate = GetFirstDayOfNextMonth(endingDate);
                }
            }
            return endingDate;
        }
        private bool IsLastDayOfMonth(DateTime date)
        {
            return date.AddDays(1).Month != date.Month;
        }
        private DateTime GetFirstDayOfNextMonth(DateTime date)
        {
            DateTime newDate;
            if (date.Month < 12)
            {
                newDate = new DateTime(date.Year, date.Month + 1, 1, date.Hour, date.Minute, date.Second);
            }
            else
            {
                newDate = new DateTime(date.Year + 1, 1, 1, date.Hour, date.Minute, date.Second);
            }
            return newDate;
        }
    }
}