public void BclThroughHistory_Scriptural()
        {
            var bcl = BclCalendars.Hebrew;
            var noda = CalendarSystem.HebrewScriptural;

            // The min supported date/time starts part way through the year
            var minYear = bcl.GetYear(bcl.MinSupportedDateTime) + 1;
            // The max supported date/time ends part way through the year
            var maxYear = bcl.GetYear(bcl.MaxSupportedDateTime) - 1;

            // Can't use BclEquivalenceHelper for this one, because of the month conversions.
            for (int year = minYear; year <= maxYear; year++)
            {
                int months = bcl.GetMonthsInYear(year);
                Assert.AreEqual(months, noda.GetMonthsInYear(year));
                for (int civilMonth = 1; civilMonth <= months; civilMonth++)
                {
                    int scripturalMonth = HebrewMonthConverter.CivilToScriptural(year, civilMonth);
                    Assert.AreEqual(bcl.GetDaysInMonth(year, civilMonth), noda.GetDaysInMonth(year, scripturalMonth),
                        "Year: {0}; Month: {1} (civil)", year, civilMonth);
                    for (int day = 1; day < bcl.GetDaysInMonth(year, civilMonth); day++)
                    {
                        DateTime bclDate = bcl.ToDateTime(year, civilMonth, day, 0, 0, 0, 0);
                        LocalDate nodaDate = new LocalDate(year, scripturalMonth, day, noda);
                        Assert.AreEqual(bclDate, nodaDate.AtMidnight().ToDateTimeUnspecified(), "{0}-{1}-{2}", year, scripturalMonth, day);
                        Assert.AreEqual(nodaDate, LocalDateTime.FromDateTime(bclDate, noda).Date);
                        Assert.AreEqual(year, nodaDate.Year);
                        Assert.AreEqual(scripturalMonth, nodaDate.Month);
                        Assert.AreEqual(day, nodaDate.Day);
                    }
                }
            }
        }
Пример #2
0
        public void Transitions2000To2010()
        {
            // These were fetched with Joda Time 1.6.2, which definitely uses the new rules.
            var expectedDates = new[]
            {
                new LocalDate(2000, 3, 30), // Thursday morning
                new LocalDate(2001, 3, 29), // Thursday morning
                new LocalDate(2002, 3, 29), // Friday morning from here onwards
                new LocalDate(2003, 3, 28),
                new LocalDate(2004, 3, 26),
                new LocalDate(2005, 4, 1),
                new LocalDate(2006, 3, 31),
                new LocalDate(2007, 3, 30),
                new LocalDate(2008, 3, 28),
                new LocalDate(2009, 3, 27),
                new LocalDate(2010, 3, 26)
            };

            for (int year = 2000; year <= 2010; year++)
            {
                LocalDate summer = new LocalDate(year, 6, 1);
                var intervalPair = Jordan.MapLocal(summer.AtMidnight());
                Assert.AreEqual(1, intervalPair.Count);
                Assert.AreEqual(expectedDates[year - 2000], intervalPair.EarlyInterval.IsoLocalStart.Date);
            }
        }
Пример #3
0
        public void GuessZoneIdByTransitionsUncached(TimeZoneInfo bclZone)
        {
            // As of March 6th 2017, the Windows time zone database hasn't caught up to
            // 2017a which reflected the change that Mongolia no longer observes DST.
            if (bclZone.Id == "Ulaanbaatar Standard Time" || bclZone.Id == "W. Mongolia Standard Time")
            {
                return;
            }

            string id = TzdbDateTimeZoneSource.Default.GuessZoneIdByTransitionsUncached(bclZone,
                                                                                        TzdbDefaultZonesForIdGuessZoneIdByTransitionsUncached);

            // Unmappable zones may not be mapped, or may be mapped to something reasonably accurate.
            // We don't mind either way.
            if (!TzdbDateTimeZoneSource.Default.WindowsMapping.PrimaryMapping.ContainsKey(bclZone.Id))
            {
                return;
            }

            Assert.IsNotNull(id, $"Unable to guess time zone for {bclZone.Id}");
            var tzdbZone = TzdbDateTimeZoneSource.Default.ForId(id);

            var       thisYear                = SystemClock.Instance.GetCurrentInstant().InUtc().Year;
            LocalDate?lastIncorrectDate       = null;
            Offset?   lastIncorrectBclOffset  = null;
            Offset?   lastIncorrectTzdbOffset = null;

            int total   = 0;
            int correct = 0;

            // From the start of this year to the end of next year, we should have an 80% hit rate or better.
            // That's stronger than the 70% we limit to in the code, because if it starts going between 70% and 80% we
            // should have another look at the algorithm. (And this is dealing with 80% of days, not 80% of transitions,
            // so it's not quite equivalent anyway.)
            for (var date = new LocalDate(thisYear, 1, 1); date.Year < thisYear + 2; date = date.PlusDays(1))
            {
                Instant startOfUtcDay = date.AtMidnight().InUtc().ToInstant();
                Offset  tzdbOffset    = tzdbZone.GetUtcOffset(startOfUtcDay);
                Offset  bclOffset     = Offset.FromTimeSpan(bclZone.GetUtcOffset(startOfUtcDay.ToDateTimeOffset()));
                if (tzdbOffset == bclOffset)
                {
                    correct++;
                }
                else
                {
                    // Useful for debugging (by having somewhere to put a breakpoint) as well as for the message.
                    lastIncorrectDate       = date;
                    lastIncorrectBclOffset  = bclOffset;
                    lastIncorrectTzdbOffset = tzdbOffset;
                }
                total++;
            }
            Assert.That(correct * 100.0 / total, Is.GreaterThanOrEqualTo(75.0),
                        "Last incorrect date for {0} vs {1}: {2} (BCL: {3}; TZDB: {4})",
                        bclZone.Id,
                        id,
                        lastIncorrectDate, lastIncorrectBclOffset, lastIncorrectTzdbOffset);
        }
Пример #4
0
        /// <summary>
        /// BidAsk AddData
        /// </summary>
        /// <remarks>
        /// Add Data on to the curve with localDate
        /// </remarks>
        /// <returns>AddBidAskOperationResult</returns>
        public AddBidAskOperationResult AddData(LocalDate localDate, string product, BidAskValue value)
        {
            if (_entity.OriginalGranularity.IsTimeGranularity())
            {
                throw new BidAskException("This MarketData has Time granularity. Use AddData(Instant time...)");
            }

            return(_addBidAsk(localDate.AtMidnight(), product, value));
        }
Пример #5
0
        public static void Today(LocalDate today)
        {
            var todayAsInstant = DateTimeZoneProviders.Tzdb
                                 .GetSystemDefault()
                                 .AtStrictly(today.AtMidnight())
                                 .ToInstant();

            Clock.Current = new FakeClock(todayAsInstant);
        }
Пример #6
0
        public void GuessZoneIdByTransitionsUncached(TimeZoneInfo bclZone)
        {
            // As of October 17th 2013, the Windows time zone database hasn't noticed that
            // Morocco delayed the DST transition in 2013, so we end up with UTC. It's
            // annoying, but it's not actually a code issue. Just ignore it for now. We
            // should check this periodically and remove the hack when it works again.
            if (bclZone.Id == "Morocco Standard Time")
            {
                return;
            }
            string id = TzdbDateTimeZoneSource.Default.GuessZoneIdByTransitionsUncached(bclZone);

            // Unmappable zones may not be mapped, or may be mapped to something reasonably accurate.
            // We don't mind either way.
            if (!TzdbDateTimeZoneSource.Default.WindowsMapping.PrimaryMapping.ContainsKey(bclZone.Id))
            {
                return;
            }

            Assert.IsNotNull(id);
            var tzdbZone = TzdbDateTimeZoneSource.Default.ForId(id);

            var       thisYear                = SystemClock.Instance.Now.InUtc().Year;
            LocalDate?lastIncorrectDate       = null;
            Offset?   lastIncorrectBclOffset  = null;
            Offset?   lastIncorrectTzdbOffset = null;

            int total   = 0;
            int correct = 0;

            // From the start of this year to the end of next year, we should have an 80% hit rate or better.
            // That's stronger than the 70% we limit to in the code, because if it starts going between 70% and 80% we
            // should have another look at the algorithm. (And this is dealing with 80% of days, not 80% of transitions,
            // so it's not quite equivalent anyway.)
            for (var date = new LocalDate(thisYear, 1, 1); date.Year < thisYear + 2; date = date.PlusDays(1))
            {
                Instant startOfUtcDay = date.AtMidnight().InUtc().ToInstant();
                Offset  tzdbOffset    = tzdbZone.GetUtcOffset(startOfUtcDay);
                Offset  bclOffset     = Offset.FromTimeSpan(bclZone.GetUtcOffset(startOfUtcDay.ToDateTimeOffset()));
                if (tzdbOffset == bclOffset)
                {
                    correct++;
                }
                else
                {
                    // Useful for debugging (by having somewhere to put a breakpoint) as well as for the message.
                    lastIncorrectDate       = date;
                    lastIncorrectBclOffset  = bclOffset;
                    lastIncorrectTzdbOffset = tzdbOffset;
                }
                total++;
            }
            Assert.That(correct * 100.0 / total, Is.GreaterThanOrEqualTo(80.0),
                        "Last incorrect date for {0}: {1} (BCL: {2}; TZDB: {3})",
                        bclZone.Id,
                        lastIncorrectDate, lastIncorrectBclOffset, lastIncorrectTzdbOffset);
        }
Пример #7
0
        /// <inheritdoc/>
        public override async Task Handle(UpdateDailyOutflow command)
        {
            var root = await _repository.Find <Wallet>(command.Target);

            if (root == null)
            {
                throw new ArgumentNullException(nameof(command.Address));
            }

            var coin = await _repository.Find <Coin>(root.Coin);

            if (coin == null)
            {
                throw new ArgumentNullException(nameof(root.Coin));
            }

            var txResults = await GetTransactions(command);

            if (txResults == null)
            {
                return;
            }

            var outflows = new Dictionary <Instant, (Instant time, double amount)>();

            foreach (var tx in txResults)
            {
                var dateTime = Instant.FromUnixTimeMilliseconds(tx.ReceiveTime).InUtc().LocalDateTime;
                var date     = new LocalDate(dateTime.Year, dateTime.Month, dateTime.Day);
                var instant  = date.AtMidnight().InUtc().ToInstant();
                var amount   = tx.Amount;
                if (tx.To == command.Target)
                {
                    amount *= -1;
                }

                if (outflows.ContainsKey(instant))
                {
                    amount += outflows[instant].amount;
                }
                outflows[instant] = (Instant.FromUnixTimeMilliseconds(tx.ReceiveTime), amount);
            }

            ICommand changeBalanceCommand = null;
            var      idx = 0;

            foreach (var v in outflows)
            {
                changeBalanceCommand = new RetroactiveCommand <ChangeWalletBalance>(new ChangeWalletBalance(command.Address, new Quantity(-v.Value.amount, coin.Asset), $"Out{command.Index}_{idx}"), v.Value.time);
                await _balanceHandler.Handle(changeBalanceCommand);

                ++idx;
            }

            command.EventType = changeBalanceCommand?.EventType;
        }
Пример #8
0
    static void Main()
    {
        var persianCalendar = CalendarSystem.GetPersianCalendar();
        var pattern         = LocalDatePattern.CreateWithInvariantCulture("yyyy-MM-dd")
                              .WithTemplateValue(new LocalDate(1393, 1, 1, persianCalendar));
        LocalDate result   = pattern.Parse("1393-02-29").Value;
        DateTime  dateTime = result.AtMidnight().ToDateTimeUnspecified();

        Console.WriteLine(dateTime);     // 19th May 2014 (Gregorian)
    }
        private int DaysSinceLastPublicHoliday(LocalDate date)
        {
            var lastHol = _publicHolidayService.LastPublicHoliday(date.AtMidnight());

            if (!lastHol.HasValue)
            {
                return(-1);
            }

            return(Period.Between(lastHol.Value, date, PeriodUnits.Days).Days);
        }
Пример #10
0
        public void SampleDateBclCompatibility()
        {
            Calendar hijri     = new HijriCalendar();
            DateTime bclDirect = new DateTime(1302, 10, 15, 0, 0, 0, 0, hijri, DateTimeKind.Unspecified);

            CalendarSystem islamicCalendar = CalendarSystem.IslamicBcl;
            LocalDate      iso             = new LocalDate(1302, 10, 15, islamicCalendar);
            DateTime       bclFromNoda     = iso.AtMidnight().ToDateTimeUnspecified();

            Assert.AreEqual(bclDirect, bclFromNoda);
        }
        public void SampleDateBclCompatibility()
        {
            Calendar hijri     = new HijriCalendar();
            DateTime bclDirect = new DateTime(1302, 10, 15, 0, 0, 0, 0, hijri, DateTimeKind.Unspecified);

            CalendarSystem islamicCalendar = CalendarSystem.GetIslamicCalendar(IslamicLeapYearPattern.Base16, IslamicEpoch.Astronomical);
            LocalDate      iso             = new LocalDate(1302, 10, 15, islamicCalendar);
            DateTime       bclFromNoda     = iso.AtMidnight().ToDateTimeUnspecified();

            Assert.AreEqual(bclDirect, bclFromNoda);
        }
 public void IsoDayOfWeek_AroundEpoch()
 {
     // Test about couple of months around the Unix epoch. If that works, I'm confident the rest will.
     LocalDate date = new LocalDate(1969, 12, 1);
     for (int i = 0; i < 60; i++)
     {
         Assert.AreEqual(
             BclConversions.ToIsoDayOfWeek(date.AtMidnight().ToDateTimeUnspecified().DayOfWeek),
             date.IsoDayOfWeek);
         date = date.PlusDays(1);
     }
 }
        public void BclUsesAstronomicalEpoch()
        {
            Calendar hijri     = new HijriCalendar();
            DateTime bclDirect = new DateTime(1, 1, 1, 0, 0, 0, 0, hijri, DateTimeKind.Unspecified);

            CalendarSystem julianCalendar     = CalendarSystem.GetJulianCalendar(4);
            LocalDate      julianIslamicEpoch = new LocalDate(622, 7, 15, julianCalendar);
            LocalDate      isoIslamicEpoch    = julianIslamicEpoch.WithCalendar(CalendarSystem.Iso);
            DateTime       bclFromNoda        = isoIslamicEpoch.AtMidnight().ToDateTimeUnspecified();

            Assert.AreEqual(bclDirect, bclFromNoda);
        }
Пример #14
0
        public void GivenReferenceTimeIsFallingInValidityInterval_ThenIsActive()
        {
            // arrange
            var referenceDay = new LocalDate(2020, 09, 09);
            var startDay     = referenceDay.PlusDays(-1);
            var bagVersion   = A.BagVersion.WithValidityInterval(startDay, startDay.PlusDays(2));

            // act
            var isActive = bagVersion.IsActive(referenceDay.AtMidnight().InUtc().ToInstant());

            // assert
            isActive.Should().BeTrue();
        }
Пример #15
0
        /// <summary>
        /// VersionedTimeSerie AddData
        /// </summary>
        /// <remarks>Add Data on to the curve
        /// Add Data on to the curve with localDate
        /// </remarks>
        /// <returns>AddTimeSerieOperationResult</returns>
        public AddTimeSerieOperationResult AddData(LocalDate localDate, double?value)
        {
            Ensure.Any.IsNotNull(_entity);

            if (_entity.OriginalGranularity.IsTimeGranularity())
            {
                throw new VersionedTimeSerieException("This MarketData has Time granularity. Use AddData(Instant time, double? value)");
            }

            var localTime = localDate.AtMidnight();

            return(_add(localTime, value));
        }
        public void DayOfWeek_AroundEpoch()
        {
            // Test about couple of months around the Unix epoch. If that works, I'm confident the rest will.
            LocalDate date = new LocalDate(1969, 12, 1);

            for (int i = 0; i < 60; i++)
            {
                Assert.AreEqual(
                    BclConversions.ToIsoDayOfWeek(date.AtMidnight().ToDateTimeUnspecified().DayOfWeek),
                    date.DayOfWeek);
                date = date.PlusDays(1);
            }
        }
Пример #17
0
        /// <summary>
        /// AuctionTimeSerie AddData
        /// </summary>
        /// <remarks>
        /// Add Data on to the curve with localDate
        /// </remarks>
        /// <returns>AddAuctionTimeSerieOperationResult</returns>
        public AddAuctionTimeSerieOperationResult AddData(LocalDate localDate, AuctionBidValue[] bid, AuctionBidValue[] offer)
        {
            Ensure.Any.IsNotNull(_entity);

            if (_entity.OriginalGranularity.IsTimeGranularity())
            {
                throw new ActualTimeSerieException("This MarketData has Time granularity. Use AddData(Instant time, AuctionBidValue[] bid, AuctionBidValue[] offer)");
            }

            var localTime = localDate.AtMidnight();

            return(_add(localTime, bid, offer));
        }
        private LocalDate NextBusinessDayAfter(LocalDate date, int days = 0)
        {
            while (days > 0 || date.IsWeekend())
            {
                if (!date.IsWeekend() && !_publicHolidayService.IsPublicHoliday(date.AtMidnight()))
                {
                    days--;
                }
                date = date.PlusDays(1);
            }

            return(date);
        }
Пример #19
0
        /// <inheritdoc/>
        public override async Task Handle(UpdateDailyMining command)
        {
            var root = await _repository.Find <Wallet>(command.Target);

            if (root == null)
            {
                throw new ArgumentNullException(nameof(command.Address));
            }

            var coin = await _repository.Find <Coin>(root.Coin);

            if (coin == null)
            {
                throw new ArgumentNullException(nameof(root.Coin));
            }

            var minedBlocks = await GetMinedBlocks(command);

            if (minedBlocks == null)
            {
                return;
            }

            var blocks = new Dictionary <Instant, (Instant time, double amount)>();

            foreach (var block in minedBlocks)
            {
                var dateTime = Instant.FromUnixTimeMilliseconds(block.Timestamp).InUtc().LocalDateTime;
                var date     = new LocalDate(dateTime.Year, dateTime.Month, dateTime.Day);
                var instant  = date.AtMidnight().InUtc().ToInstant();
                var amount   = block.Feereward;
                if (blocks.ContainsKey(instant))
                {
                    amount += blocks[instant].amount;
                }
                blocks[instant] = (Instant.FromUnixTimeMilliseconds(block.Timestamp), amount);
            }

            ICommand mineCommand = null;
            var      idx         = 0;

            foreach (var v in blocks)
            {
                mineCommand = new RetroactiveCommand <MineCoin>(new MineCoin(command.Address, new Quantity(v.Value.amount, coin.Asset), $"Mining{command.Index}_{idx}"), v.Value.time);
                await _mineHandler.Handle(mineCommand);

                ++idx;
            }

            command.EventType = mineCommand?.EventType;
        }
        public Task unposted_entry_throws(LocalDate openedOn, GeneralLedgerEntryNumber generalLedgerEntryNumber,
                                          EquityAccount retainedEarnings, GeneralLedgerEntryIdentifier generalLedgerEntryIdentifier,
                                          GeneralLedgerEntryIdentifier closingGeneralLedgerEntryIdentifier)
        {
            var period    = AccountingPeriod.Open(openedOn);
            var closingOn = openedOn.AtMidnight();

            var accountingPeriodClosing = new AccountingPeriodClosing {
                Period    = period.ToString(),
                ClosingOn = Time.Format.LocalDateTime(closingOn),
                RetainedEarningsAccountNumber = retainedEarnings.AccountNumber.ToInt32(),
                ClosingGeneralLedgerEntryId   = closingGeneralLedgerEntryIdentifier.ToGuid(),
                GeneralLedgerEntryIds         = new[] { generalLedgerEntryIdentifier.ToGuid() }
            };

            return(new Scenario()
                   .Given(GeneralLedger.Identifier,
                          new GeneralLedgerOpened {
                OpenedOn = Time.Format.LocalDate(openedOn)
            },
                          accountingPeriodClosing)
                   .Given(ChartOfAccounts.Identifier,
                          new AccountDefined {
                AccountName = retainedEarnings.AccountName.ToString(),
                AccountNumber = retainedEarnings.AccountNumber.ToInt32()
            })
                   .Given(GeneralLedgerEntry.FormatStreamIdentifier(generalLedgerEntryIdentifier),
                          new GeneralLedgerEntryCreated {
                GeneralLedgerEntryId = generalLedgerEntryIdentifier.ToGuid(),
                Number = generalLedgerEntryNumber.ToString(),
                Period = period.ToString(),
                CreatedOn = Time.Format.LocalDateTime(openedOn.AtMidnight())
            })
                   .When(accountingPeriodClosing)
                   .Throws(new GeneralLedgerEntryWasNotPostedException(generalLedgerEntryIdentifier))
                   .Assert(_handler, _facts));
        }
Пример #21
0
        /// <summary>
        ///     Generate prayer times for one day at given date.
        /// </summary>
        /// <param name="when">
        ///     <see cref="Instant" /> value which represents the date.
        /// </param>
        /// <param name="settings">
        ///     Settings containing parameters for calculating prayer times.
        /// </param>
        /// <param name="coordinate">
        ///     Location's coordinate.
        /// </param>
        /// <param name="timeZone">
        ///     Location's time zone.
        /// </param>
        /// <returns>
        ///     <see cref="Prayers" /> object containing prayer times for one day at given date.
        /// </returns>
        internal static Prayers GetPrayerTimesForOneDay(Instant when, [NotNull] PrayerCalculationSettings settings, Geocoordinate coordinate, double timeZone)
        {
            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            var utc    = when.InUtc();
            var year   = utc.Year;
            var month  = utc.Month;
            var day    = utc.Day;
            var local  = new LocalDate(year, month, day);
            var newUtc = new ZonedDateTime(local.AtMidnight(), DateTimeZone.Utc, Offset.Zero);

            var jd              = newUtc.ToInstant().ToJulianDate() - (coordinate.Longitude / 360.0);
            var raw             = ComputeRaw(jd, settings, coordinate.Latitude, coordinate.Altitude);
            var afterAdjustment = AdjustTime(raw, settings, coordinate.Longitude, timeZone);

            // Calculate midnight.
            var fajr    = afterAdjustment.Fajr;
            var sunrise = afterAdjustment.Sunrise;
            var sunset  = afterAdjustment.Sunset;

            afterAdjustment.Midnight = ComputeMidnightTime(settings.CalculationMethod.MidnightMethod, fajr, sunrise, sunset);

            // Convert.
            var converted = ConvertFromFloatingPointFormat(afterAdjustment, year, month, day, timeZone);

            // Round.
            var rounded = new Prayers(RoundPrayerTime(converted.Imsak),
                                      RoundPrayerTime(converted.Fajr),
                                      RoundPrayerTime(converted.Sunrise),
                                      RoundPrayerTime(converted.Dhuha),
                                      RoundPrayerTime(converted.Zuhr),
                                      RoundPrayerTime(converted.Asr),
                                      RoundPrayerTime(converted.Sunset),
                                      RoundPrayerTime(converted.Maghrib),
                                      RoundPrayerTime(converted.Isha),
                                      RoundPrayerTime(converted.Midnight));

            return(rounded);
        }
        [Test, Timeout(180000)] // Can take a long time under NCrunch.
        public void BclThroughHistory()
        {
            Calendar hijri     = new HijriCalendar();
            DateTime bclDirect = new DateTime(1, 1, 1, 0, 0, 0, 0, hijri, DateTimeKind.Unspecified);

            CalendarSystem islamicCalendar    = CalendarSystem.GetIslamicCalendar(IslamicLeapYearPattern.Base16, IslamicEpoch.Astronomical);
            CalendarSystem julianCalendar     = CalendarSystem.GetJulianCalendar(4);
            LocalDate      julianIslamicEpoch = new LocalDate(622, 7, 15, julianCalendar);
            LocalDate      islamicDate        = julianIslamicEpoch.WithCalendar(islamicCalendar);

            for (int i = 0; i < 9000 * 365; i++)
            {
                Assert.AreEqual(bclDirect, islamicDate.AtMidnight().ToDateTimeUnspecified());
                Assert.AreEqual(hijri.GetYear(bclDirect), islamicDate.Year, i.ToString());
                Assert.AreEqual(hijri.GetMonth(bclDirect), islamicDate.Month);
                Assert.AreEqual(hijri.GetDayOfMonth(bclDirect), islamicDate.Day);
                bclDirect   = hijri.AddDays(bclDirect, 1);
                islamicDate = islamicDate.PlusDays(1);
            }
        }
Пример #23
0
        [Test, Timeout(300000)] // Can take a long time under NCrunch.
        public void BclThroughHistory()
        {
            Calendar       bcl  = new PersianCalendar();
            CalendarSystem noda = CalendarSystem.GetPersianCalendar();

            for (int year = 1; year < 9378; year++)
            {
                for (int month = 1; month < 13; month++)
                {
                    Assert.AreEqual(bcl.GetDaysInMonth(year, month), noda.GetDaysInMonth(year, month),
                                    "Year: {0}; Month: {1}", year, month);
                    for (int day = 1; day < bcl.GetDaysInMonth(year, month); day++)
                    {
                        DateTime  bclDate  = new DateTime(year, month, day, bcl);
                        LocalDate nodaDate = new LocalDate(year, month, day, noda);
                        Assert.AreEqual(bclDate, nodaDate.AtMidnight().ToDateTimeUnspecified());
                        Assert.AreEqual(nodaDate, LocalDateTime.FromDateTime(bclDate).WithCalendar(noda).Date);
                        Assert.AreEqual(year, nodaDate.Year);
                        Assert.AreEqual(month, nodaDate.Month);
                        Assert.AreEqual(day, nodaDate.Day);
                    }
                }
            }
        }
Пример #24
0
 public static Slice From(LocalDate start, string timezone)
 {
     return(new Slice(start.AtMidnight().InZoneStrictly(DateTimeZoneProviders.Tzdb[timezone])));
 }
Пример #25
0
 /// <summary>
 /// Gets the number of ticks a period represents based on a given start date.
 /// </summary>
 /// <param name="period">The period.</param>
 /// <param name="start">The start.</param>
 /// <returns></returns>
 public static long TicksFrom([NotNull] this Period period, LocalDate start)
 {
     return(Period.Between(start.AtMidnight(), start.AtMidnight() + period, PeriodUnits.Ticks).Ticks);
 }
Пример #26
0
 /// <summary>
 /// Gets the number of ticks a between a start and end date.
 /// </summary>
 /// <param name="start">The start.</param>
 /// <param name="end">The end.</param>
 /// <returns></returns>
 public static long TicksTo(this LocalDate start, LocalDate end)
 {
     return(Period.Between(start.AtMidnight(), end.AtMidnight(), PeriodUnits.Ticks).Ticks);
 }
Пример #27
0
 public static int NumberOfHoursInDay(this LocalDate date, DateTimeZone timezone)
 {
     EnsureArg.IsNotNull(timezone);
     return((int)(date.PlusDays(1).AtMidnight().InZoneStrictly(timezone).ToInstant() - date.AtMidnight().InZoneStrictly(timezone).ToInstant()).ToTimeSpan().TotalHours);
 }
Пример #28
0
 /// <summary>
 /// Set Most Recent date range version selection
 /// </summary>
 /// <param name="start"></param>
 /// <param name="end"></param>
 /// <returns></returns>
 public VersionedQuery ForMostRecent(LocalDate start, LocalDate end)
 {
     return(ForMostRecent(start.AtMidnight(), end.AtMidnight()));
 }
        public void GuessZoneIdByTransitionsUncached(TimeZoneInfo bclZone)
        {
            // As of October 17th 2013, the Windows time zone database hasn't noticed that
            // Morocco delayed the DST transition in 2013, so we end up with UTC. It's
            // annoying, but it's not actually a code issue. Just ignore it for now. We
            // should check this periodically and remove the hack when it works again.
            // Likewise Libya has somewhat odd representation in the BCL. Worth looking at more closely later.
            if (bclZone.Id == "Morocco Standard Time" || bclZone.Id == "Libya Standard Time")
            {
                return;
            }
            // See https://github.com/nodatime/nodatime/issues/440
            // This time zone was apparently a mistake in both IANA and Windows; it's now effectively
            // been removed from IANA (America/Santa_Isabel is now a link to America/Tijuana) but while Windows
            // has it, we know we won't get a decent answer.
            if (bclZone.Id == "Pacific Standard Time (Mexico)")
            {
                return;
            }
            string id = TzdbDateTimeZoneSource.Default.GuessZoneIdByTransitionsUncached(bclZone);

            // Unmappable zones may not be mapped, or may be mapped to something reasonably accurate.
            // We don't mind either way.
            if (!TzdbDateTimeZoneSource.Default.WindowsMapping.PrimaryMapping.ContainsKey(bclZone.Id))
            {
                return;
            }

            Assert.IsNotNull(id);
            var tzdbZone = TzdbDateTimeZoneSource.Default.ForId(id);

            var       thisYear                = SystemClock.Instance.GetCurrentInstant().InUtc().Year;
            LocalDate?lastIncorrectDate       = null;
            Offset?   lastIncorrectBclOffset  = null;
            Offset?   lastIncorrectTzdbOffset = null;

            int total   = 0;
            int correct = 0;

            // From the start of this year to the end of next year, we should have an 80% hit rate or better.
            // That's stronger than the 70% we limit to in the code, because if it starts going between 70% and 80% we
            // should have another look at the algorithm. (And this is dealing with 80% of days, not 80% of transitions,
            // so it's not quite equivalent anyway.)
            for (var date = new LocalDate(thisYear, 1, 1); date.Year < thisYear + 2; date = date.PlusDays(1))
            {
                Instant startOfUtcDay = date.AtMidnight().InUtc().ToInstant();
                Offset  tzdbOffset    = tzdbZone.GetUtcOffset(startOfUtcDay);
                Offset  bclOffset     = Offset.FromTimeSpan(bclZone.GetUtcOffset(startOfUtcDay.ToDateTimeOffset()));
                if (tzdbOffset == bclOffset)
                {
                    correct++;
                }
                else
                {
                    // Useful for debugging (by having somewhere to put a breakpoint) as well as for the message.
                    lastIncorrectDate       = date;
                    lastIncorrectBclOffset  = bclOffset;
                    lastIncorrectTzdbOffset = tzdbOffset;
                }
                total++;
            }
            Assert.That(correct * 100.0 / total, Is.GreaterThanOrEqualTo(75.0),
                        "Last incorrect date for {0} vs {1}: {2} (BCL: {3}; TZDB: {4})",
                        bclZone.Id,
                        id,
                        lastIncorrectDate, lastIncorrectBclOffset, lastIncorrectTzdbOffset);
        }
        public Task period_closing_started(LocalDate openedOn, EquityAccount retainedEarnings,
                                           AssetAccount cashAccount, IncomeAccount incomeAccount, ExpenseAccount expenseAccount,
                                           GeneralLedgerEntryIdentifier[] generalLedgerEntryIdentifiers,
                                           GeneralLedgerEntryIdentifier closingGeneralLedgerEntryIdentifier, Money income, Money expense)
        {
            var period = AccountingPeriod.Open(openedOn);

            var closingOn = openedOn.AtMidnight();

            var accountingPeriodClosing = new AccountingPeriodClosing {
                Period    = period.ToString(),
                ClosingOn = Time.Format.LocalDateTime(closingOn),
                RetainedEarningsAccountNumber = retainedEarnings.AccountNumber.ToInt32(),
                ClosingGeneralLedgerEntryId   = closingGeneralLedgerEntryIdentifier.ToGuid(),
                GeneralLedgerEntryIds         =
                    Array.ConvertAll(generalLedgerEntryIdentifiers, identifier => identifier.ToGuid())
            };
            var net = income - expense;
            var generalLedgerEntryFacts = generalLedgerEntryIdentifiers.SelectMany(
                (identifier, index) => Array.ConvertAll(new object[] {
                new GeneralLedgerEntryCreated {
                    Number               = $"sale-{index}",
                    Period               = period.ToString(),
                    CreatedOn            = Time.Format.LocalDate(openedOn),
                    GeneralLedgerEntryId = identifier.ToGuid()
                },
                new CreditApplied {
                    Amount               = income.ToDecimal(),
                    AccountNumber        = incomeAccount.AccountNumber.ToInt32(),
                    GeneralLedgerEntryId = identifier.ToGuid()
                },
                new DebitApplied {
                    Amount               = expense.ToDecimal(),
                    AccountNumber        = expenseAccount.AccountNumber.ToInt32(),
                    GeneralLedgerEntryId = identifier.ToGuid()
                },
                net > Money.Zero
                                                        ? new DebitApplied {
                    Amount               = net.ToDecimal(),
                    AccountNumber        = cashAccount.AccountNumber.ToInt32(),
                    GeneralLedgerEntryId = identifier.ToGuid()
                }
                                                        : new CreditApplied {
                    Amount               = -net.ToDecimal(),
                    AccountNumber        = cashAccount.AccountNumber.ToInt32(),
                    GeneralLedgerEntryId = identifier.ToGuid()
                },
                new GeneralLedgerEntryPosted {
                    Period = period.ToString(),
                    GeneralLedgerEntryId = identifier.ToGuid()
                },
            }, e => new Fact(GeneralLedgerEntry.FormatStreamIdentifier(identifier), e)))
                                          .ToArray();

            return(new Scenario()
                   .Given(ChartOfAccounts.Identifier,
                          new AccountDefined {
                AccountName = cashAccount.AccountName.ToString(),
                AccountNumber = cashAccount.AccountNumber.ToInt32()
            },
                          new AccountDefined {
                AccountName = incomeAccount.AccountName.ToString(),
                AccountNumber = incomeAccount.AccountNumber.ToInt32()
            },
                          new AccountDefined {
                AccountName = expenseAccount.AccountName.ToString(),
                AccountNumber = expenseAccount.AccountNumber.ToInt32()
            },
                          new AccountDefined {
                AccountName = retainedEarnings.AccountName.ToString(),
                AccountNumber = retainedEarnings.AccountNumber.ToInt32()
            })
                   .Given(GeneralLedger.Identifier,
                          new GeneralLedgerOpened {
                OpenedOn = Time.Format.LocalDate(openedOn)
            },
                          accountingPeriodClosing)
                   .Given(generalLedgerEntryFacts)
                   .When(accountingPeriodClosing)
                   .Then(GeneralLedger.Identifier,
                         new GeneralLedgerEntryCreated {
                CreatedOn = Time.Format.LocalDateTime(closingOn),
                GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid(),
                Number = $"jec-{period}",
                Period = period.ToString()
            },
                         new DebitApplied {
                Amount = income.ToDecimal() * generalLedgerEntryIdentifiers.Length,
                AccountNumber = incomeAccount.AccountNumber.ToInt32(),
                GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid()
            },
                         new CreditApplied {
                Amount = expense.ToDecimal() * generalLedgerEntryIdentifiers.Length,
                AccountNumber = expenseAccount.AccountNumber.ToInt32(),
                GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid()
            },
                         net < Money.Zero
                                                ? new DebitApplied {
                Amount = -net.ToDecimal() * generalLedgerEntryIdentifiers.Length,
                AccountNumber = retainedEarnings.AccountNumber.ToInt32(),
                GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid()
            }
                                                : new CreditApplied {
                Amount = net.ToDecimal() * generalLedgerEntryIdentifiers.Length,
                AccountNumber = retainedEarnings.AccountNumber.ToInt32(),
                GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid()
            },
                         new GeneralLedgerEntryPosted {
                Period = period.ToString(),
                GeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid()
            },
                         new AccountingPeriodClosed {
                Period = period.ToString(),
                GeneralLedgerEntryIds = Array.ConvertAll(generalLedgerEntryIdentifiers,
                                                         identifier => identifier.ToGuid()),
                ClosingGeneralLedgerEntryId = closingGeneralLedgerEntryIdentifier.ToGuid(),
                Balance = new[] {
                    new BalanceLineItem {
                        AccountNumber = cashAccount.AccountNumber.ToInt32(),
                        Amount = net.ToDecimal() * generalLedgerEntryIdentifiers.Length
                    },
                    new BalanceLineItem {
                        AccountNumber = retainedEarnings.AccountNumber.ToInt32(),
                        Amount = net.ToDecimal() * generalLedgerEntryIdentifiers.Length
                    },
                    new BalanceLineItem {
                        AccountNumber = incomeAccount.AccountNumber.ToInt32(),
                        Amount = Money.Zero.ToDecimal()
                    },
                    new BalanceLineItem {
                        AccountNumber = expenseAccount.AccountNumber.ToInt32(),
                        Amount = Money.Zero.ToDecimal()
                    }
                }
            })
                   .Assert(_handler, _facts));
        }
 /// <summary>
 /// Performs conversion from source to destination type
 /// </summary>
 /// <param name="source">Source object</param>
 /// <param name="destination">Destination object</param>
 /// <param name="context">Resolution context</param>
 /// <returns>Destination object</returns>
 public DateTime?Convert(LocalDate?source, DateTime?destination, ResolutionContext context)
 => source?.AtMidnight().ToDateTimeUnspecified() ?? destination;
Пример #32
0
 /// <summary>
 /// Gets the number of ticks a between a start and end date.
 /// </summary>
 /// <param name="start">The start.</param>
 /// <param name="end">The end.</param>
 /// <returns></returns>
 public static long TicksTo(this LocalDate start, LocalDate end)
 {
     return Period.Between(start.AtMidnight(), end.AtMidnight(), PeriodUnits.Ticks).Ticks;
 }
        public void GuessZoneIdByTransitionsUncached(TimeZoneInfo bclZone)
        {
            // As of April 21st 2016, the Windows time zone database hasn't caught up to
            // 2016d which includes: "America/Caracas switches from -0430 to -04 on 2016-05-01 at 02:30"
            // Still need to investigate Morocco...
            if (bclZone.Id == "Venezuela Standard Time" || bclZone.Id == "Morocco Standard Time")
            {
                return;
            }

            string id = TzdbDateTimeZoneSource.Default.GuessZoneIdByTransitionsUncached(bclZone);

            // Unmappable zones may not be mapped, or may be mapped to something reasonably accurate.
            // We don't mind either way.
            if (!TzdbDateTimeZoneSource.Default.WindowsMapping.PrimaryMapping.ContainsKey(bclZone.Id))
            {
                return;
            }

            Assert.IsNotNull(id, $"Unable to guess time zone for {bclZone.Id}");
            var tzdbZone = TzdbDateTimeZoneSource.Default.ForId(id);

            var thisYear = SystemClock.Instance.GetCurrentInstant().InUtc().Year;
            LocalDate? lastIncorrectDate = null;
            Offset? lastIncorrectBclOffset = null;
            Offset? lastIncorrectTzdbOffset = null;

            int total = 0;
            int correct = 0;
            // From the start of this year to the end of next year, we should have an 80% hit rate or better.
            // That's stronger than the 70% we limit to in the code, because if it starts going between 70% and 80% we
            // should have another look at the algorithm. (And this is dealing with 80% of days, not 80% of transitions,
            // so it's not quite equivalent anyway.)
            for (var date = new LocalDate(thisYear, 1, 1); date.Year < thisYear + 2; date = date.PlusDays(1))
            {
                Instant startOfUtcDay = date.AtMidnight().InUtc().ToInstant();
                Offset tzdbOffset = tzdbZone.GetUtcOffset(startOfUtcDay);
                Offset bclOffset = Offset.FromTimeSpan(bclZone.GetUtcOffset(startOfUtcDay.ToDateTimeOffset()));
                if (tzdbOffset == bclOffset)
                {
                    correct++;
                }
                else
                {
                    // Useful for debugging (by having somewhere to put a breakpoint) as well as for the message.
                    lastIncorrectDate = date;
                    lastIncorrectBclOffset = bclOffset;
                    lastIncorrectTzdbOffset = tzdbOffset;
                }
                total++;
            }
            Assert.That(correct * 100.0 / total, Is.GreaterThanOrEqualTo(75.0),
                "Last incorrect date for {0} vs {1}: {2} (BCL: {3}; TZDB: {4})",
                bclZone.Id,
                id,
                lastIncorrectDate, lastIncorrectBclOffset, lastIncorrectTzdbOffset);
        }
Пример #34
0
 /// <summary>
 /// Gets the number of ticks a period represents based on a given start date.
 /// </summary>
 /// <param name="period">The period.</param>
 /// <param name="start">The start.</param>
 /// <returns></returns>
 public static long TicksFrom([NotNull] this Period period, LocalDate start)
 {
     return Period.Between(start.AtMidnight(), start.AtMidnight() + period, PeriodUnits.Ticks).Ticks;
 }
        public void GuessZoneIdByTransitionsUncached(TimeZoneInfo bclZone)
        {
            // As of October 17th 2013, the Windows time zone database hasn't noticed that
            // Morocco delayed the DST transition in 2013, so we end up with UTC. It's
            // annoying, but it's not actually a code issue. Just ignore it for now. We
            // should check this periodically and remove the hack when it works again.
            // Likewise Libya has somewhat odd representation in the BCL. Worth looking at more closely later.
            if (bclZone.Id == "Morocco Standard Time" || bclZone.Id == "Libya Standard Time")
            {
                return;
            }
            string id = TzdbDateTimeZoneSource.Default.GuessZoneIdByTransitionsUncached(bclZone);

            // Unmappable zones may not be mapped, or may be mapped to something reasonably accurate.
            // We don't mind either way.
            if (!TzdbDateTimeZoneSource.Default.WindowsMapping.PrimaryMapping.ContainsKey(bclZone.Id))
            {
                return;
            }

            Assert.IsNotNull(id);
            var tzdbZone = TzdbDateTimeZoneSource.Default.ForId(id);

            var thisYear = SystemClock.Instance.GetCurrentInstant().InUtc().Year;
            LocalDate? lastIncorrectDate = null;
            Offset? lastIncorrectBclOffset = null;
            Offset? lastIncorrectTzdbOffset = null;

            int total = 0;
            int correct = 0;
            // From the start of this year to the end of next year, we should have an 80% hit rate or better.
            // That's stronger than the 70% we limit to in the code, because if it starts going between 70% and 80% we
            // should have another look at the algorithm. (And this is dealing with 80% of days, not 80% of transitions,
            // so it's not quite equivalent anyway.)
            for (var date = new LocalDate(thisYear, 1, 1); date.Year < thisYear + 2; date = date.PlusDays(1))
            {
                Instant startOfUtcDay = date.AtMidnight().InUtc().ToInstant();
                Offset tzdbOffset = tzdbZone.GetUtcOffset(startOfUtcDay);
                Offset bclOffset = Offset.FromTimeSpan(bclZone.GetUtcOffset(startOfUtcDay.ToDateTimeOffset()));
                if (tzdbOffset == bclOffset)
                {
                    correct++;
                }
                else
                {
                    // Useful for debugging (by having somewhere to put a breakpoint) as well as for the message.
                    lastIncorrectDate = date;
                    lastIncorrectBclOffset = bclOffset;
                    lastIncorrectTzdbOffset = tzdbOffset;
                }
                total++;
            }
            Assert.That(correct * 100.0 / total, Is.GreaterThanOrEqualTo(75.0),
                "Last incorrect date for {0} vs {1}: {2} (BCL: {3}; TZDB: {4})",
                bclZone.Id,
                id,
                lastIncorrectDate, lastIncorrectBclOffset, lastIncorrectTzdbOffset);
        }
 public void AtMidnight()
 {
     LocalDate date = new LocalDate(2011, 6, 29);
     LocalDateTime expected = new LocalDateTime(2011, 6, 29, 0, 0, 0);
     Assert.AreEqual(expected, date.AtMidnight());
 }
        public void SampleDateBclCompatibility()
        {
            Calendar hijri = BclCalendars.Hijri;
            DateTime bclDirect = hijri.ToDateTime(1302, 10, 15, 0, 0, 0, 0);

            CalendarSystem islamicCalendar = CalendarSystem.IslamicBcl;
            LocalDate iso = new LocalDate(1302, 10, 15, islamicCalendar);
            DateTime bclFromNoda = iso.AtMidnight().ToDateTimeUnspecified();
            Assert.AreEqual(bclDirect, bclFromNoda);
        }
Пример #38
0
 public LocalDateTimeRange ToLocalDateTimeRange()
 {
     return(new LocalDateTimeRange(_start.AtMidnight(), _end.AtMidnight()));
 }
Пример #39
0
        private static DateCalculator CreateDateCalculator(LocalDate londonDate, params LocalDate[] bankHolidayDates)
        {
            var londonMidnight = londonDate.AtMidnight().InZoneStrictly(LondonTimeZone).ToInstant();

            return(CreateDateCalculator(londonMidnight, bankHolidayDates));
        }