)]}'
{
  "commit": "6734566311926e81038b3e40eb1317f8cf58770e",
  "tree": "4fb87c0943d9e245cc70464bcd85dfc22a64944c",
  "parents": [
    "aa380aea6d0e64de9801d6793339dca128f6a401"
  ],
  "author": {
    "name": "Brian Cairns",
    "email": "bcairns@google.com",
    "time": "Tue Apr 05 13:32:21 2022 -0600"
  },
  "committer": {
    "name": "Brian Cairns",
    "email": "bcairns@google.com",
    "time": "Tue Apr 05 13:33:57 2022 -0600"
  },
  "message": "Fix duration handling on .NET Core.\n\nAppSheet\u0027s version of EPPlus added a hack for OLE Automation dates for\nvalues that use specific formatting styles (20, 21, 45, 46, 47) which\nwe consider \"durations\".\n\nSee: https://github.com/closedxml/closedxml/wiki/\n     NumberFormatId-Lookup-Table\n\nFor these \"duration\" date fields, we don\u0027t use the .NET built-in\nDateTime.FromOADate(double) method because we believed it returned the\n\"wrong\" value. Specifically, we treat the double value as an absolute\noffset from 1899-12-30 00:00. For dates after 1899-12-30 00:00, this is\nclose enough (though see notes about rounding), but for dates before\n1899-12-30 00:00 AppSheet\u0027s behavior is wrong. Specifically, on an OLE\nAutomation date, the negative sign *only* affects the integer portion\nof the double, *not* the fractional portion. So, for example, -0.5 and\n0.5 are the same OLE Automation date, and -1.5 means \"0.5 days after 1\nday before 1899-12-30 00:00\", *not* \"1.5 days before 1899-12-30 00:00\".\n\nUnfortunately, this busted behavior is baked into the AppSheet codebase,\nand it\u0027s been this way for a long time. \"Fixing\" this behavior would\nbreak existing apps that use Excel and have dates before 1899-12-30 or\nnegative durations.\n\nThe current implementation has another unfortunate problem - it only has\nmillisecond precision because of the way that TimeSpan.FromDays works.\nIn .NET Framework, this doesn\u0027t seem to matter because DateTime has\nlimited precision anyway, but in .NET Core it results in weird rounding\nissues.\n\nThis change attempts to work around the rounding issues while preserving\nthe existing (broken) AppSheet behavior. It also adds tests for both\n.NET Framework and .NET Core to verify the \"correct\" functionality.\n\nChange-Id: Iefda8bd95583b28aae49e0fb97ab4716b155acf8\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "02fa8212080fef7e8da0e30ba3e17a747816821d",
      "old_mode": 33188,
      "old_path": "EPPlus.sln",
      "new_id": "f41280f2d7371724419c690c02bd7e9a50aa2e2b",
      "new_mode": 33188,
      "new_path": "EPPlus.sln"
    },
    {
      "type": "modify",
      "old_id": "42fc4ae50f0481ae656f17109b6ad2775db2c818",
      "old_mode": 33188,
      "old_path": "EPPlus/EPPlusSDK.csproj",
      "new_id": "4a28eebeb0cb3996621a6322a7fdf0f61fa4e80b",
      "new_mode": 33188,
      "new_path": "EPPlus/EPPlusSDK.csproj"
    },
    {
      "type": "modify",
      "old_id": "2d1371f57d0632fb4d3890e2a684f1ba37d1b518",
      "old_mode": 33188,
      "old_path": "EPPlus/ExcelWorksheet.cs",
      "new_id": "c194e88931bacd5bb1c783613d7bb88f804c83d5",
      "new_mode": 33188,
      "new_path": "EPPlus/ExcelWorksheet.cs"
    },
    {
      "type": "modify",
      "old_id": "046e2db89c3ebf276fa93d1213515bea7d63e84f",
      "old_mode": 33188,
      "old_path": "EPPlusTest/EPPlusTest.csproj",
      "new_id": "4cc7ac50defc785bbc1bdc8abbc59808da799a1c",
      "new_mode": 33188,
      "new_path": "EPPlusTest/EPPlusTest.csproj"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "a8daf6df9f945651b5079ff7791e38476c824e4f",
      "new_mode": 33188,
      "new_path": "NetCoreTests/NetCoreTests.csproj"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "fc4a71c4d8122d5174e725352842f158da5e3905",
      "new_mode": 33188,
      "new_path": "NetCoreTests/TestWorkbooks/Times.xlsx"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "39cc038210334690897bd3895624e4b1976e4066",
      "new_mode": 33188,
      "new_path": "NetCoreTests/TimeTest.cs"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "242fcf5f6bb4a0efdfde497b963c37023068cd52",
      "new_mode": 33188,
      "new_path": "NetFrameworkTests/NetFrameworkTests.csproj"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "fc4a71c4d8122d5174e725352842f158da5e3905",
      "new_mode": 33188,
      "new_path": "NetFrameworkTests/TestWorkbooks/Times.xlsx"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "1ddddbe0270cd7cd97465d1c0140320c16710a64",
      "new_mode": 33188,
      "new_path": "NetFrameworkTests/TimeTest.cs"
    }
  ]
}
