public ExcelValue YEAR(List <ExcelValue> args, ExpressionScope scope) { if (args.NotDecimal(0, null, out double serial)) { return(ExcelValue.NA); } if (serial == 0) { return(new ExcelValue.DecimalValue(1900, scope.OutLanguage, ExpressionFormat.General)); } var date = ExcelValue.FromDateSerial(serial); if (date.HasValue) { return(new ExcelValue.DecimalValue(date.Value.Year, scope.OutLanguage, ExpressionFormat.General)); } return(ExcelValue.VALUE); }
public ExcelValue DATEDIF(List <ExcelValue> args, ExpressionScope scope) { if (args.NotDecimal(0, null, out double serial1)) { return(ExcelValue.VALUE); } if (args.NotDecimal(1, null, out double serial2)) { return(ExcelValue.VALUE); } if (serial1 < 0 || serial2 < 0 || serial1 > serial2) { return(ExcelValue.VALUE); } var dv1 = ExcelValue.FromDateSerial(serial1); if (!dv1.HasValue) { return(ExcelValue.NA); } var dv2 = ExcelValue.FromDateSerial(serial2); if (!dv2.HasValue) { return(ExcelValue.NA); } if (args.NotText(2, null, scope.OutLanguage, out string unit)) { return(ExcelValue.NA); } var d1 = dv1.Value; var d2 = dv2.Value; double result; switch (unit.ToUpperInvariant()) { case "Y": result = d2.Year - d1.Year - (d2.Month >= d1.Month && d2.Day >= d1.Day ? 0 : 1); break; case "M": result = 12 * (d2.Year - d1.Year) + (d2.Month - d1.Month); break; case "D": result = Math.Round((d2 - d1).TotalDays); break; case "MD": result = d2.Day - d1.Day; break; case "YM": result = d2.Month - d1.Month; if (result < 0) { result += 12; } break; case "YD": var tmpD1 = new DateTime(d1.Year + (d2.Month >= d1.Month && d2.Day >= d1.Day ? 1 : 0), d1.Month, d1.Day); result = Math.Round((d2 - tmpD1).TotalDays); break; default: return(ExcelValue.VALUE); } return(new ExcelValue.DecimalValue(result, scope.OutLanguage)); }