Skip to content

Commit

Permalink
Merge pull request #10 from TheCrossLegCoder/chore/cross-touch
Browse files Browse the repository at this point in the history
feat: add ability to parse Nepali Date with AutoAdjust functionality
  • Loading branch information
TheCrossLegCoder authored Apr 22, 2023
2 parents 53597c1 + 865b492 commit 6b3f429
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 40 deletions.
70 changes: 50 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,54 +71,56 @@ using NepDate;

var nepDate = new NepaliDate("2079/12/16");

// get the Nepali year, month, and day values
var year = nepDate.Year;
var month = nepDate.Month;
var day = nepDate.Day;
// get Nepali year, month, and day values
var year = nepDate.Year; // 2079
var month = nepDate.Month; // 12
var day = nepDate.Day; // 16
// get the equivalent English date as a DateTime
var englishDate = nepDate.EnglishDate;
var englishDate = nepDate.EnglishDate; // 2023/03/30
// get the day of the week as a DayOfWeek enum value
var dayOfWeek = nepDate.DayOfWeek;
var dayOfWeek = nepDate.DayOfWeek; // Thursday
// get the last day of the month as an integer value
var monthEndDay = nepDate.MonthEndDay;
var monthEndDay = nepDate.MonthEndDay; // 30
// get the last day of the month as a NepaliDate object
var monthEndDate = nepDate.MonthEndDate;
var monthEndDate = nepDate.MonthEndDate; // 2079/12/30
// get the name of the month as a NepaliMonths enum
var monthName = nepDate.MonthName;
var monthName = nepDate.MonthName; // Chaitra
```

### Additional Functions

```csharp
using NepDate;

var nepDate = DateTime.Now.ToNepaliDate();
var nepDate = new NepaliDate("2079/12/16");

// get the equivalent Nepali date as string
var nepDateAsString = nepDate.ToString();
var nepDateAsString = nepDate.ToString(); // 2079/12/16
// determine if the Nepali year is a leap year
var isLeapYear = nepDate.IsLeapYear();
var isLeapYear = nepDate.IsLeapYear(); // False
// add or subtract days from a Nepali date
var newDate = nepDate.AddDays(10);
var newDate = nepDate.AddDays(30); // 2080/01/16
// get next month as a NepDate object
var nextMonth = nepDate.NextMonth();
// get next month as a NepaliDate object
var nextMonth = nepDate.NextMonth(); // NepaliDate obj with value 2080/01/01
var nextMonth = nepDate.NextMonth(returnFirstDay: false); // NepaliDate obj with value 2080/01/16
// get previous month as a NepDate object
var prevMonth = nepDate.PreviousMonth();
// get previous month as a NepaliDate object
var prevMonth = nepDate.PreviousMonth(); // NepaliDate obj with value 2079/11/01
var prevMonth = nepDate.PreviousMonth(returnFirstDay: false); // NepaliDate obj with value 2079/11/16
// subtract two Nepali dates to get a TimeSpan object
var nepDate2 = new NepaliDate("2080/12/16");
var timeSpan = nepDate2 - nepDate;
var timeSpan = nepDate2 - nepDate; // Timespan object with value 365.00:00:00
// or
var timeSpan = nepDate2.Subtract(nepDate);
var timeSpan = nepDate2.Subtract(nepDate); // Timespan object with value 365.00:00:00
// check if a string is a valid Nepali date and convert it to a NepaliDate object
if (NepaliDate.TryParse("2079/13/16", out var result))
Expand Down Expand Up @@ -165,6 +167,29 @@ var convertedToBS = DateTime.Now.ToNepaliDate().ToString();
var convertedToAD = NepaliDate.Parse("2079/12/16").EnglishDate;
```

### Parsing Nepali Date With `AutoAdjust`
```csharp
// Parsing will try it's best to accurately identify the year, month and day
// And returns the date in the standard format of "yyyy/MM/dd"
// Below exmaples will demonstrate the probabilities.

// Replaces "_" To "/", Returns without adjusting if is already adjusted
var nepDate = NepaliDate.Parse("2077_05_25", autoAdjust: true); // 2077/05/25
// Replaces "-" To "/", Identifies '25' as day, '05' as month and '077' as year '2077'
var nepDate = NepaliDate.Parse("25-05-077", autoAdjust: true); // 2077/05/25
// Replaces "." To "/", Identifies '05' as month and '25' as day
var nepDate = NepaliDate.Parse("05.25.2077", autoAdjust: true); // 2077/05/25
// As '06' is on middle, Identifies it as month and '05' as day
var nepDate = NepaliDate.Parse("05/06/2077", autoAdjust: true); // 2077/06/05
// Identifies '05' as month due to parm 'monthInMiddle = false' and '06' as day
var nepDate = NepaliDate.Parse("05/06/2077", autoAdjust: true, monthInMiddle: false); // 2077/05/06
```

## Performance

NepDate is distinguished by its capacity to perform with exceptional speed while utilizing minimal runtime memory resources. The metrics presented below exemplify NepDate's remarkable efficiency and proficiency, while remaining mindful of resource consumption.
Expand Down Expand Up @@ -208,6 +233,11 @@ Intel Core i5-10400 CPU 2.90GHz, 1 CPU, 12 logical and 6 physical cores
| NepaliCalendar `BS -> AD` | 169,622.5 | 377.10 | 334.29 | 5️⃣ | 230 |
| NepaliCalendar `AD -> BS` | 488,003.8 | 1,433.94 | 1,271.15 | 6️⃣ | 312 |

### Contributions

## Change logs
https://github.com/TheCrossLegCoder/NepDate/releases


## Contributions

Please view the [CONTRIBUTING](https://github.com/TheCrossLegCoder/NepDate/blob/main/CONTRIBUTING.md) guide for more information.
90 changes: 70 additions & 20 deletions src/NepDate/NepaliDate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,30 +55,42 @@ public NepaliDate(int yearBs, int monthBs, int dayBs)
/// <param name="rawNepaliDate">The raw Nepali date string in the format "YYYY/MM/DD".</param>
public NepaliDate(string rawNepaliDate)
{
const byte splitLength = 3;
(Year, Month, Day) = SplitNepaliDate(rawNepaliDate);

if (string.IsNullOrEmpty(rawNepaliDate))
{
throw new InvalidNepaliDateArgumentException();
}
EnglishDate = Handlers.NepToEng.GetEnglishDate(Year, Month, Day);

if (DateTime.TryParse(rawNepaliDate, out DateTime result))
{
rawNepaliDate = result.ToString("yyyy/MM/dd");
}
ValidateAndThrow();
}

string trimmedDate = rawNepaliDate.Trim().Replace("-", "/");
string[] splitDate = trimmedDate.Split('/');
public NepaliDate(string rawNepaliDate, bool autoAdjust, bool monthInMiddle = true)
{
const int currentMillennium = 2;

if (splitDate.Length != splitLength)
(Year, Month, Day) = SplitNepaliDate(rawNepaliDate);

if (autoAdjust)
{
throw new InvalidNepaliDateFormatException();
if (Day.ToString().Length >= 3 || Day > 32)
{
(Year, Day) = (Day, Year);
}

if (!monthInMiddle)
{
(Month, Day) = (Day, Month);
}

if (Month > 12 && Day < 12)
{
(Month, Day) = (Day, Month);
}

if (Year.ToString().Length <= 3)
{
Year = int.Parse(string.Concat(currentMillennium.ToString(), Year.ToString("D3")));
}
}

Year = int.Parse(splitDate[0]);
Month = int.Parse(splitDate[1]);
Day = int.Parse(splitDate[2]);

EnglishDate = Handlers.NepToEng.GetEnglishDate(Year, Month, Day);

ValidateAndThrow();
Expand Down Expand Up @@ -243,7 +255,21 @@ public static bool TryParse(string rawNepDate, out NepaliDate result)
{
try
{
result = new NepaliDate(rawNepDate);
result = Parse(rawNepDate);
return true;
}
catch
{
result = default;
return false;
}
}

public static bool TryParse(string rawNepDate, out NepaliDate result, bool autoAdjust, bool monthInMiddle = true)
{
try
{
result = Parse(rawNepDate, autoAdjust, monthInMiddle);
return true;
}
catch
Expand All @@ -258,11 +284,35 @@ public static bool TryParse(string rawNepDate, out NepaliDate result)
/// </summary>
/// <param name="rawNepDate">The raw Nepali date string in the format "YYYY/MM/DD".</param>
/// <returns>A NepaliDate object that is equivalent to the Nepali date contained in rawNepDate.</returns>
public static NepaliDate Parse(string rawNepDate)
public static NepaliDate Parse(string rawNepaliDate)
{
return new NepaliDate(rawNepaliDate);
}

public static NepaliDate Parse(string rawNepaliDate, bool autoAdjust, bool monthInMiddle = true)
{
return new NepaliDate(rawNepDate);
return new NepaliDate(rawNepaliDate, autoAdjust, monthInMiddle);
}

private static (int year, int month, int day) SplitNepaliDate(string rawNepaliDate)
{
const byte splitLength = 3;
if (string.IsNullOrEmpty(rawNepaliDate))
{
throw new InvalidNepaliDateArgumentException();
}

string trimmedDate = rawNepaliDate.Trim().Replace("-", "/").Replace(".", "/").Replace("_", "/");
string[] splitDate = trimmedDate.Split('/');

if (splitDate.Length != splitLength)
{
throw new InvalidNepaliDateFormatException();
}
return (int.Parse(splitDate[0]), int.Parse(splitDate[1]), int.Parse(splitDate[2]));
}


/// <summary>
/// Returns a string that represents the current NepaliDate object in the format "yyyy/MM/dd".
/// </summary>
Expand Down

0 comments on commit 6b3f429

Please sign in to comment.