Skip to content

Commit 2c7d739

Browse files
committed
Release version 2.0.0.
1 parent 1f469e0 commit 2c7d739

File tree

10 files changed

+308
-159
lines changed

10 files changed

+308
-159
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## [2.0.0]
2+
3+
* Convert a [PersianDate] to [DateTime].
4+
* Added some utility methods to [PersianDate].
5+
16
## [1.2.0]
27

38
* Better lints, a more complete example.

analysis_options.yaml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,6 @@ analyzer:
2222
dead_code: error
2323
duplicate_import: error
2424
file_names: error
25-
implicit_dynamic_function: ignore
26-
implicit_dynamic_parameter: error
27-
implicit_dynamic_list_literal: ignore
28-
implicit_dynamic_map_literal: ignore
29-
implicit_dynamic_method: ignore
30-
implicit_dynamic_type: ignore
31-
implicit_dynamic_variable: ignore
3225
invalid_assignment: error
3326
missing_return: error
3427
prefer_const_constructors: error

lib/persian.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ library persian;
33

44
import 'dart:core';
55

6+
import 'package:persian/src/date_utils.dart';
7+
68
part 'src/humanizer.dart';
79
part 'src/int_extensions.dart';
810
part 'src/extensions.dart';

lib/src/date.dart

Lines changed: 44 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,15 @@
1-
part of persian;
2-
3-
int _getJulianDayNumber(int year, int month, int day) {
4-
return (((year + ((month - 8) ~/ 6) + 100100) * 1461) ~/ 4) +
5-
((153 * ((month + 9) % 12) + 2) ~/ 5) +
6-
day -
7-
34840408 -
8-
((((year + 100100 + ((month - 8) ~/ 6)) ~/ 100) * 3) ~/ 4) +
9-
752;
10-
}
1+
part of '../persian.dart';
112

123
/// An instant in Persian calendar, such as Farvardin 11, 1365.
134
class PersianDate {
145
/// Creates a [PersianDate] from the Persian year, month and day.
156
///
167
/// Example: PersianDate(1400, 12, 29);
17-
const PersianDate(
18-
this.year,
19-
this.month,
20-
this.day,
21-
);
8+
const PersianDate(this.year, this.month, this.day);
229

2310
/// Creates a [PersianDate] from the equivalent [DateTime].
2411
factory PersianDate.fromDateTime(DateTime date) {
25-
final julianDayNumber =
26-
_getJulianDayNumber(date.year, date.month, date.day);
27-
final int year = date.year;
28-
int persianYear = year - 621;
29-
final r = _PersianDateCalculation.calculate(persianYear);
30-
final int jdn1f = _getJulianDayNumber(year, 3, r.march);
31-
int k = julianDayNumber - jdn1f;
32-
// Find number of days that passed since 1 Farvardin.
33-
if (k >= 0) {
34-
if (k <= 185) {
35-
// The first 6 months.
36-
final int jm = 1 + (k ~/ 31);
37-
final int jd = (k % 31) + 1;
38-
39-
return PersianDate(persianYear, jm, jd);
40-
} else {
41-
// The remaining months.
42-
k -= 186;
43-
}
44-
} else {
45-
// Previous Persian year.
46-
persianYear -= 1;
47-
k += 179;
48-
if (r.leap == 1) k += 1;
49-
}
50-
final int jm = 7 + (k ~/ 30);
51-
final int jd = (k % 30) + 1;
52-
53-
return PersianDate(persianYear, jm, jd);
12+
return toPersian(date.year, date.month, date.day);
5413
}
5514

5615
/// Constructs a new [PersianDate] instance
@@ -67,10 +26,8 @@ class PersianDate {
6726
bool isUtc = false,
6827
}) =>
6928
PersianDate.fromDateTime(
70-
DateTime.fromMillisecondsSinceEpoch(
71-
millisecondsSinceEpoch,
72-
isUtc: isUtc,
73-
),
29+
DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
30+
isUtc: isUtc),
7431
);
7532

7633
/// Constructs a new [PersianDate] instance
@@ -86,10 +43,8 @@ class PersianDate {
8643
bool isUtc = false,
8744
}) =>
8845
PersianDate.fromDateTime(
89-
DateTime.fromMicrosecondsSinceEpoch(
90-
microsecondsSinceEpoch,
91-
isUtc: isUtc,
92-
),
46+
DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch,
47+
isUtc: isUtc),
9348
);
9449

9550
/// The Year.
@@ -101,109 +56,54 @@ class PersianDate {
10156
/// The Day.
10257
final int day;
10358

104-
@override
105-
String toString() {
106-
return '$year/${month.toString().padLeft(2, '0')}/${day.toString().padLeft(2, '0')}'
107-
.withPersianNumbers();
59+
/// Converts this [PersianDate] instance to a [DateTime].
60+
DateTime toDateTime() {
61+
return toGregorian(year, month, day);
10862
}
109-
}
110-
111-
/// Internal class
112-
class _PersianDateCalculation {
113-
const _PersianDateCalculation({
114-
required this.leap,
115-
required this.gy,
116-
required this.march,
117-
});
118-
119-
/// This determines if the Persian Year is
120-
/// leap (366-day long) or is the common year (365 days), and
121-
/// finds the day in March (Gregorian calendar) of the first
122-
/// day of the Persian Year.
123-
///
124-
/// [1. see here](http://www.astro.uni.torun.pl/~kb/Papers/EMP/PersianC-EMP.htm)
125-
///
126-
/// [2. see here](http://www.fourmilab.ch/documents/calendar/)
127-
factory _PersianDateCalculation.calculate(int persianYear) {
128-
// Persian years starting the 33-year rule.
12963

130-
final int bl = breaks.length;
131-
final int gy = persianYear + 621;
132-
int leapJ = -14;
133-
int jp = breaks[0];
134-
int jump = 0;
64+
/// Checks whether a Persian date is valid or not.
65+
static bool isValidPersianDate(
66+
int persianYear, int persianMonth, int persianDay) {
67+
return persianYear >= -61 &&
68+
persianYear <= 3177 &&
69+
persianMonth >= 1 &&
70+
persianMonth <= 12 &&
71+
persianDay >= 1 &&
72+
persianDay <= getDaysInPersianMonth(persianYear, persianMonth);
73+
}
13574

136-
// should not happen
137-
if (persianYear < -61 || persianYear >= 3178) {
138-
throw StateError('should not happen');
75+
/// Get the number of days in a Persian year.
76+
static int getDaysInPersianYear(int persianYear) {
77+
if (isLeapPersianYear(persianYear)) {
78+
return 366;
13979
}
14080

141-
// Find the limiting years for the Persian year jy.
142-
for (int i = 1; i < bl; i += 1) {
143-
final int jm = breaks[i];
144-
jump = jm - jp;
145-
if (persianYear < jm) {
146-
break;
147-
}
148-
leapJ = leapJ + (jump ~/ 33) * 8 + (((jump % 33)) ~/ 4);
149-
jp = jm;
150-
}
151-
int n = persianYear - jp;
81+
return 365;
82+
}
15283

153-
// Find the number of leap years from AD 621 to the beginning
154-
// of the current Persian year in the Persian calendar.
155-
leapJ = leapJ + ((n) ~/ 33) * 8 + (((n % 33) + 3) ~/ 4);
156-
if ((jump % 33) == 4 && jump - n == 4) {
157-
leapJ += 1;
84+
/// Number of days in a given month in a Persian year.
85+
static int getDaysInPersianMonth(int persianYear, int persianMonth) {
86+
if (persianMonth < 7) {
87+
return 31;
15888
}
159-
160-
// And the same in the Gregorian calendar (until the year gy).
161-
final int leapG = ((gy) ~/ 4) - (((((gy) ~/ 100) + 1) * 3) ~/ 4) - 150;
162-
163-
// Determine the Gregorian date of Farvardin the 1st.
164-
final int march = 20 + leapJ - leapG;
165-
166-
// Find how many years have passed since the last leap year.
167-
if (jump - n < 6) {
168-
n = n - jump + ((jump + 4) ~/ 33) * 33;
89+
if (persianMonth < 12) {
90+
return 30;
16991
}
170-
int leap = ((((n + 1) % 33) - 1) % 4);
171-
if (leap == -1) {
172-
leap = 4;
92+
if (isLeapPersianYear(persianYear)) {
93+
return 30;
17394
}
17495

175-
return _PersianDateCalculation(leap: leap, gy: gy, march: march);
96+
return 29;
17697
}
17798

178-
/// Number of years since the last leap year (0 to 4)
179-
final int leap;
180-
181-
/// Gregorian year of the beginning of Persian year
182-
final int gy;
183-
184-
/// The March day of Farvardin the 1st (1st day of jy)
185-
final int march;
99+
/// Is this a leap year or not?
100+
static bool isLeapPersianYear(int persianYear) {
101+
return persianCalendar(persianYear)!.leap == 0;
102+
}
186103

187-
static final List<int> breaks = const [
188-
-61,
189-
9,
190-
38,
191-
199,
192-
426,
193-
686,
194-
756,
195-
818,
196-
1111,
197-
1181,
198-
1210,
199-
1635,
200-
2060,
201-
2097,
202-
2192,
203-
2262,
204-
2324,
205-
2394,
206-
2456,
207-
3178,
208-
];
104+
@override
105+
String toString() {
106+
return '$year/${month.toString().padLeft(2, '0')}/${day.toString().padLeft(2, '0')}'
107+
.withPersianNumbers();
108+
}
209109
}

0 commit comments

Comments
 (0)