Skip to content

Commit

Permalink
Merge pull request #18 from shahabfar/release
Browse files Browse the repository at this point in the history
add extensions for DateOnly struct to support date conversions
  • Loading branch information
shahabfar authored Mar 29, 2024
2 parents e37e374 + 56e43d1 commit d80a326
Show file tree
Hide file tree
Showing 11 changed files with 593 additions and 19 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,3 +266,12 @@ var persianDate = islamicDate.ToPersianDateOnly().ToString();
// Print the Persian date
Console.WriteLine(persianDate);
```
### Enhanced DateOnly Support in Persia.Net
With this enhancement, you can directly convert a `DateOnly` object to a `PersianDateTime` or an `IslamicDateTime` object. This means you no longer need to first convert `DateOnly` to a `DateTime` object before converting to `PersianDateTime` or `IslamicDateTime`. This reduces the steps involved, making your code more efficient and readable.

Here’s an example of how you can now directly convert a `DateOnly` object to a `PersianDateTime`:
```csharp
DateOnly dateOnly = // a DateOnly object comes from...;
PersianDateTime persianDate = dateOnly.ToPersianDateTime();
```
All the `DateTime` extensions that have been introduced by Persia.Net have also been extended to the `DateOnly` struct. That is, all the methods and properties you’re accustomed to using with `DateTime` objects are now directly accessible on `DateOnly` objects.
24 changes: 24 additions & 0 deletions src/Persia.Net.Test/IslamicDateOnlyTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace Persia.Net.Test;

public class IslamicDateOnlyTests
{
[Fact]
public void Test_ConvertToIslamicDate_ReturnCorrectDate()
{
// Arrange
DateOnly nonNullableDate = new DateOnly(2024, 03, 26);
DateOnly? nullableDate = new DateOnly(2024, 03, 26);

// Act
var convertedNonNullableDate = nonNullableDate.ToIslamicDateTime();
var convertedNullableDate = nullableDate.ToIslamicDateTime();

// Assert
Assert.Equal(16, convertedNonNullableDate.Day);
Assert.Equal(09, convertedNonNullableDate.Month);
Assert.Equal(1445, convertedNonNullableDate.Year);
Assert.Equal(16, convertedNullableDate.Day);
Assert.Equal(09, convertedNullableDate.Month);
Assert.Equal(1445, convertedNullableDate.Year);
}
}
67 changes: 67 additions & 0 deletions src/Persia.Net.Test/PersianDateOnlyTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
namespace Persia.Net.Test;

public class PersianDateOnlyTests
{
[Fact]
public void Test_ConvertToPersianDate_ReturnCorrectDate()
{
// Arrange
DateOnly? nullableDate = new DateOnly(2024, 03, 29);
DateOnly nonNullableDate = new DateOnly(2024, 03, 29);

// Act
var convertedNullableDate = nullableDate.ToPersianDateTime();
var convertedNonNullableDate = nonNullableDate.ToPersianDateTime();

// Assert
Assert.Equal(10, convertedNullableDate.Day);
Assert.Equal(1, convertedNullableDate.Month);
Assert.Equal(1403, convertedNullableDate.Year);

Assert.Equal(10, convertedNonNullableDate.Day);
Assert.Equal(01, convertedNonNullableDate.Month);
Assert.Equal(1403, convertedNonNullableDate.Year);
}

//[Fact]
//public void Test_HumanizePersianDateTimePassed_ReturnCorrectText()
//{
// // Arrange
// var date = new DateOnly(2022, 03, 25);

// // Act
// //var humanizedPersian = date.HumanizePassedPersianDateTime();
// var humanizedPersian = date.HumanizePassedPersianDateTime(TimeUnit.Days);

// // Assert
// Assert.Equal("‫۱۱ ماه و ۳۶۲ روز و ۲ ساعت پیش‬", humanizedPersian);
//}

[Fact]
public void Test_GetNextCurrentPreviousDayWeekMonth_ReturnCorrectDate()
{
// Arrange
var date = new DateOnly(2024, 03, 19);
DateOnly? nullableDate = new DateOnly(2024, 03, 19);

// Act
var nextDay = nullableDate.NextPersianDay();
var prevDay = date.PreviousPersianDay();
var currentWeek = date.CurrentPersianWeek();
var nextWeek = date.NextPersianWeek();
var previousWeek = date.PreviousPersianWeek();
var currentMonth = date.CurrentPersianMonth();
var nextMonth = date.NextPersianMonth();
var previousMonth = date.PreviousPersianMonth();

// Assert
Assert.Equal(new PersianDateTime(1403, 01, 01), nextDay);
Assert.Equal(new PersianDateTime(1402, 12, 28), prevDay);
Assert.Equal(new PersianDateTime(1403, 01, 01), currentWeek[4]);
Assert.Equal(new PersianDateTime(1403, 01, 04), nextWeek[0]);
Assert.Equal(new PersianDateTime(1402, 12, 25), previousWeek[6]);
Assert.Equal(new PersianDateTime(1402, 12, 26), currentMonth[25]);
Assert.Equal(new PersianDateTime(1403, 01, 03), nextMonth[2]);
Assert.Equal(new PersianDateTime(1402, 11, 30), previousMonth[29]);
}
}
26 changes: 25 additions & 1 deletion src/Persia.Net/Converter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,30 @@ internal static PersianDateTime ConvertToPersian(DateTime date)
// Convert the Julian Day Number to a Persian date
var persianDate = JulianDayToPersian(jd);

// Get the progress of the year for the Persian date
var (dayOfYear, daysRemainingInYear) = GetYearProgress(persianDate.Year, DateOnly.FromDateTime(date));

persianDate.SetYearProgress(dayOfYear, daysRemainingInYear);
var daysInMonth = GetDaysInPersianMonth(persianDate.Year, persianDate.Month);
persianDate.SetDaysInMonth(daysInMonth);
var ticks = CalculatePersianTicks(persianDate);
persianDate.SetTicks(ticks);
return persianDate;
}

/// <summary>
/// Converts a Gregorian date to a Persian date.
/// </summary>
/// <param name="date">The Gregorian date to be converted.</param>
/// <returns>A PersianDateTime object representing the converted Persian date.</returns>
internal static PersianDateTime ConvertToPersian(DateOnly date)
{
// Convert the Gregorian date to Julian Day Number
var jd = GregorianToJulianDay(date.Year, date.Month, date.Day);

// Convert the Julian Day Number to a Persian date
var persianDate = JulianDayToPersian(jd);

// Get the progress of the year for the Persian date
var (dayOfYear, daysRemainingInYear) = GetYearProgress(persianDate.Year, date);

Expand Down Expand Up @@ -142,7 +166,7 @@ private static DateOnly JulianDayToGregorian(double julianDay)
/// <param name="year">The year in the Persian calendar.</param>
/// <param name="date">The date for which to calculate the year progress.</param>
/// <returns>A tuple containing the day of the year and the number of days remaining in the year.</returns>
private static (int DayOfYear, int DaysRemainingInYear) GetYearProgress(int year, DateTime date)
private static (int DayOfYear, int DaysRemainingInYear) GetYearProgress(int year, DateOnly date)
{
// Calculate the JDN (Julian Day Number) for the start and end of the year
var jdnStartOfYear = PersianToJulianDay(year, 1, 1);
Expand Down
Loading

0 comments on commit d80a326

Please sign in to comment.