@@ -1395,6 +1395,17 @@ TValue DoAddYears(const TValue& date, i64 years, const NUdf::IDateBuilder& build
1395
1395
}
1396
1396
};
1397
1397
1398
+ template <auto Core>
1399
+ TUnboxedValue SimpleDatetimeToDatetimeUdf (const IValueBuilder* valueBuilder, const TUnboxedValuePod* args) {
1400
+ auto result = args[0 ];
1401
+ auto & storage = Reference (result);
1402
+ if (auto res = Core (storage, *valueBuilder)) {
1403
+ storage = res.GetRef ();
1404
+ return result;
1405
+ }
1406
+ return TUnboxedValuePod{};
1407
+ }
1408
+
1398
1409
TMaybe<TTMStorage> StartOfYear (TTMStorage storage, const IValueBuilder& valueBuilder) {
1399
1410
storage.Month = 1 ;
1400
1411
storage.Day = 1 ;
@@ -1408,16 +1419,31 @@ TValue DoAddYears(const TValue& date, i64 years, const NUdf::IDateBuilder& build
1408
1419
return storage;
1409
1420
}
1410
1421
BEGIN_SIMPLE_STRICT_ARROW_UDF (TStartOfYear, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
1411
- auto result = args[0 ];
1412
- auto & storage = Reference (result);
1413
- if (auto res = StartOfYear (storage, *valueBuilder)) {
1414
- storage = res.GetRef ();
1415
- return result;
1416
- }
1417
- return TUnboxedValuePod{};
1422
+ return SimpleDatetimeToDatetimeUdf<StartOfYear>(valueBuilder, args);
1418
1423
}
1419
1424
END_SIMPLE_ARROW_UDF (TStartOfYear, TStartOfKernelExec<StartOfYear>::Do);
1420
1425
1426
+ void SetEndOfDay (TTMStorage& storage) {
1427
+ storage.Hour = 23 ;
1428
+ storage.Minute = 59 ;
1429
+ storage.Second = 59 ;
1430
+ storage.Microsecond = 999999 ;
1431
+ }
1432
+
1433
+ TMaybe<TTMStorage> EndOfYear (TTMStorage storage, const IValueBuilder& valueBuilder) {
1434
+ storage.Month = 12 ;
1435
+ storage.Day = 31 ;
1436
+ SetEndOfDay (storage);
1437
+ if (!storage.Validate (valueBuilder.GetDateBuilder ())) {
1438
+ return {};
1439
+ }
1440
+ return storage;
1441
+ }
1442
+ BEGIN_SIMPLE_STRICT_ARROW_UDF (TEndOfYear, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
1443
+ return SimpleDatetimeToDatetimeUdf<EndOfYear>(valueBuilder, args);
1444
+ }
1445
+ END_SIMPLE_ARROW_UDF (TEndOfYear, TStartOfKernelExec<EndOfYear>::Do);
1446
+
1421
1447
TMaybe<TTMStorage> StartOfQuarter (TTMStorage storage, const IValueBuilder& valueBuilder) {
1422
1448
storage.Month = (storage.Month - 1 ) / 3 * 3 + 1 ;
1423
1449
storage.Day = 1 ;
@@ -1431,16 +1457,24 @@ TValue DoAddYears(const TValue& date, i64 years, const NUdf::IDateBuilder& build
1431
1457
return storage;
1432
1458
}
1433
1459
BEGIN_SIMPLE_STRICT_ARROW_UDF (TStartOfQuarter, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
1434
- auto result = args[0 ];
1435
- auto & storage = Reference (result);
1436
- if (auto res = StartOfQuarter (storage, *valueBuilder)) {
1437
- storage = res.GetRef ();
1438
- return result;
1439
- }
1440
- return TUnboxedValuePod{};
1460
+ return SimpleDatetimeToDatetimeUdf<StartOfQuarter>(valueBuilder, args);
1441
1461
}
1442
1462
END_SIMPLE_ARROW_UDF (TStartOfQuarter, TStartOfKernelExec<StartOfQuarter>::Do);
1443
1463
1464
+ TMaybe<TTMStorage> EndOfQuarter (TTMStorage storage, const IValueBuilder& valueBuilder) {
1465
+ storage.Month = ((storage.Month - 1 ) / 3 + 1 ) * 3 ;
1466
+ storage.Day = NMiniKQL::GetMonthLength (storage.Month , NMiniKQL::IsLeapYear (storage.Year ));
1467
+ SetEndOfDay (storage);
1468
+ if (!storage.Validate (valueBuilder.GetDateBuilder ())) {
1469
+ return {};
1470
+ }
1471
+ return storage;
1472
+ }
1473
+ BEGIN_SIMPLE_STRICT_ARROW_UDF (TEndOfQuarter, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
1474
+ return SimpleDatetimeToDatetimeUdf<EndOfQuarter>(valueBuilder, args);
1475
+ }
1476
+ END_SIMPLE_ARROW_UDF (TEndOfQuarter, TStartOfKernelExec<EndOfQuarter>::Do);
1477
+
1444
1478
TMaybe<TTMStorage> StartOfMonth (TTMStorage storage, const IValueBuilder& valueBuilder) {
1445
1479
storage.Day = 1 ;
1446
1480
storage.Hour = 0 ;
@@ -1453,37 +1487,21 @@ TValue DoAddYears(const TValue& date, i64 years, const NUdf::IDateBuilder& build
1453
1487
return storage;
1454
1488
}
1455
1489
BEGIN_SIMPLE_STRICT_ARROW_UDF (TStartOfMonth, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
1456
- auto result = args[0 ];
1457
- auto & storage = Reference (result);
1458
- if (auto res = StartOfMonth (storage, *valueBuilder)) {
1459
- storage = res.GetRef ();
1460
- return result;
1461
- }
1462
- return TUnboxedValuePod{};
1490
+ return SimpleDatetimeToDatetimeUdf<StartOfMonth>(valueBuilder, args);
1463
1491
}
1464
1492
END_SIMPLE_ARROW_UDF (TStartOfMonth, TStartOfKernelExec<StartOfMonth>::Do);
1465
1493
1466
1494
TMaybe<TTMStorage> EndOfMonth (TTMStorage storage, const IValueBuilder& valueBuilder) {
1467
1495
storage.Day = NMiniKQL::GetMonthLength (storage.Month , NMiniKQL::IsLeapYear (storage.Year ));
1468
- storage.Hour = 0 ;
1469
- storage.Minute = 0 ;
1470
- storage.Second = 0 ;
1471
- storage.Microsecond = 0 ;
1472
-
1496
+ SetEndOfDay (storage);
1473
1497
if (!storage.Validate (valueBuilder.GetDateBuilder ())) {
1474
1498
return {};
1475
1499
}
1476
1500
return storage;
1477
1501
}
1478
1502
1479
1503
BEGIN_SIMPLE_STRICT_ARROW_UDF (TEndOfMonth, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
1480
- auto result = args[0 ];
1481
- auto & storage = Reference (result);
1482
- if (auto res = EndOfMonth (storage, *valueBuilder)) {
1483
- storage = res.GetRef ();
1484
- return result;
1485
- }
1486
- return TUnboxedValuePod{};
1504
+ return SimpleDatetimeToDatetimeUdf<EndOfMonth>(valueBuilder, args);
1487
1505
}
1488
1506
END_SIMPLE_ARROW_UDF (TEndOfMonth, TStartOfKernelExec<EndOfMonth>::Do);
1489
1507
@@ -1497,20 +1515,36 @@ TValue DoAddYears(const TValue& date, i64 years, const NUdf::IDateBuilder& build
1497
1515
storage.Minute = 0 ;
1498
1516
storage.Second = 0 ;
1499
1517
storage.Microsecond = 0 ;
1518
+ if (!storage.Validate (valueBuilder.GetDateBuilder ())) {
1519
+ return {};
1520
+ }
1500
1521
return storage;
1501
1522
}
1502
1523
1503
1524
BEGIN_SIMPLE_STRICT_ARROW_UDF (TStartOfWeek, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
1504
- auto result = args[0 ];
1505
- auto & storage = Reference (result);
1506
- if (auto res = StartOfWeek (storage, *valueBuilder)) {
1507
- storage = res.GetRef ();
1508
- return result;
1509
- }
1510
- return TUnboxedValuePod{};
1525
+ return SimpleDatetimeToDatetimeUdf<StartOfWeek>(valueBuilder, args);
1511
1526
}
1512
1527
END_SIMPLE_ARROW_UDF (TStartOfWeek, TStartOfKernelExec<StartOfWeek>::Do);
1513
1528
1529
+ TMaybe<TTMStorage> EndOfWeek (TTMStorage storage, const IValueBuilder& valueBuilder) {
1530
+ const ui32 shift = 86400u * (7u - storage.DayOfWeek );
1531
+ auto dt = storage.ToDatetime (valueBuilder.GetDateBuilder ());
1532
+ if (NUdf::MAX_DATETIME - shift <= dt) {
1533
+ return {};
1534
+ }
1535
+ storage.FromDatetime (valueBuilder.GetDateBuilder (), dt + shift, storage.TimezoneId );
1536
+ SetEndOfDay (storage);
1537
+ if (!storage.Validate (valueBuilder.GetDateBuilder ())) {
1538
+ return {};
1539
+ }
1540
+ return storage;
1541
+ }
1542
+
1543
+ BEGIN_SIMPLE_STRICT_ARROW_UDF (TEndOfWeek, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
1544
+ return SimpleDatetimeToDatetimeUdf<EndOfWeek>(valueBuilder, args);
1545
+ }
1546
+ END_SIMPLE_ARROW_UDF (TEndOfWeek, TStartOfKernelExec<EndOfWeek>::Do);
1547
+
1514
1548
TMaybe<TTMStorage> StartOfDay (TTMStorage storage, const IValueBuilder& valueBuilder) {
1515
1549
storage.Hour = 0 ;
1516
1550
storage.Minute = 0 ;
@@ -1524,16 +1558,24 @@ TValue DoAddYears(const TValue& date, i64 years, const NUdf::IDateBuilder& build
1524
1558
}
1525
1559
1526
1560
BEGIN_SIMPLE_STRICT_ARROW_UDF (TStartOfDay, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
1527
- auto result = args[0 ];
1528
- auto & storage = Reference (result);
1529
- if (auto res = StartOfDay (storage, *valueBuilder)) {
1530
- storage = res.GetRef ();
1531
- return result;
1532
- }
1533
- return TUnboxedValuePod{};
1561
+ return SimpleDatetimeToDatetimeUdf<StartOfDay>(valueBuilder, args);
1534
1562
}
1535
1563
END_SIMPLE_ARROW_UDF (TStartOfDay, TStartOfKernelExec<StartOfDay>::Do);
1536
1564
1565
+ TMaybe<TTMStorage> EndOfDay (TTMStorage storage, const IValueBuilder& valueBuilder) {
1566
+ SetEndOfDay (storage);
1567
+ auto & builder = valueBuilder.GetDateBuilder ();
1568
+ if (!storage.Validate (builder)) {
1569
+ return {};
1570
+ }
1571
+ return storage;
1572
+ }
1573
+
1574
+ BEGIN_SIMPLE_STRICT_ARROW_UDF (TEndOfDay, TOptional<TResource<TMResourceName>>(TAutoMap<TResource<TMResourceName>>)) {
1575
+ return SimpleDatetimeToDatetimeUdf<EndOfDay>(valueBuilder, args);
1576
+ }
1577
+ END_SIMPLE_ARROW_UDF (TEndOfDay, TStartOfKernelExec<EndOfDay>::Do);
1578
+
1537
1579
TMaybe<TTMStorage> StartOf (TTMStorage storage, ui64 interval, const IValueBuilder& valueBuilder) {
1538
1580
if (interval >= 86400000000ull ) {
1539
1581
// treat as StartOfDay
@@ -2375,7 +2417,11 @@ TValue DoAddYears(const TValue& date, i64 years, const NUdf::IDateBuilder& build
2375
2417
TShiftQuarters,
2376
2418
TShiftMonths,
2377
2419
2420
+ TEndOfYear,
2421
+ TEndOfQuarter,
2378
2422
TEndOfMonth,
2423
+ TEndOfWeek,
2424
+ TEndOfDay,
2379
2425
2380
2426
TToUnits<ToSecondsName, ui32, 1 >,
2381
2427
TToUnits<ToMillisecondsName, ui64, 1000 >,
0 commit comments