From 63c24a9ebda44a072a243a28a555335677dd5462 Mon Sep 17 00:00:00 2001 From: am3n Date: Fri, 21 Jan 2022 12:46:20 +0330 Subject: [PATCH 01/14] update lib versions --- app/src/main/AndroidManifest.xml | 3 ++- build.gradle | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c249739..0e1d640 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,7 +8,8 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> - + diff --git a/build.gradle b/build.gradle index d7caa17..c04d8a9 100644 --- a/build.gradle +++ b/build.gradle @@ -2,13 +2,13 @@ buildscript { ext { - appCompat = '1.3.0' - material = '1.4.0' - persianDate = '1.1' + appCompat = '1.4.1' + material = '1.5.0' + persianDate = '1.3.4' libraryMinSdk = 14 - libraryTargetSdk = 30 - libraryCompileSdkVersion = 30 + libraryTargetSdk = 31 + libraryCompileSdkVersion = 31 } repositories { google() From 7e1ee1e3781fd557795248993909681ffbf5b15c Mon Sep 17 00:00:00 2001 From: am3n Date: Fri, 21 Jan 2022 13:48:30 +0330 Subject: [PATCH 02/14] enable to use PersianDatePicker as a view in layouts --- app/src/main/res/font/shabnam_light_fd.ttf | Bin 0 -> 94960 bytes app/src/main/res/layout/activity_main.xml | 9 +++++ .../persiandatepicker/PersianDatePicker.java | 36 ++++++++++-------- .../view/PersianNumberPicker.java | 3 ++ .../src/main/res/values/attrs.xml | 4 ++ 5 files changed, 36 insertions(+), 16 deletions(-) create mode 100644 app/src/main/res/font/shabnam_light_fd.ttf diff --git a/app/src/main/res/font/shabnam_light_fd.ttf b/app/src/main/res/font/shabnam_light_fd.ttf new file mode 100644 index 0000000000000000000000000000000000000000..38cd346bfc31f2cb55775a27649ce84b796d83d2 GIT binary patch literal 94960 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

)+S)$+YszE{ilYWZF*->c<&wS2FZ z@740v6b*h_zE|7dtL1yOe6N;Yul29j^6RzydM&?R%dgk+>$UuPEx%sNuh;VHwf^;5 ze!Z4oujSWk`Sn`9Ps{gd`93Y*r{(*!e4m!@)AD^P#x42pL&4D590GRxCJ|``}h|%tMC_6 zvvkcoiu)lgK@-98eIvoB>Qt|0+;o;&UR+dB=2?{Ys(hKJsG_`hQMqqX-mlyE7PTn@ zAFB=Jd3rCZ@YX4W?YLjOEmT-hUS3h+xFi&f6k;h|I>k3k^J0kI^~%w36c0v>PlXQ6 zZ^ajt&2P$=j?e-=-(3v{^z{1%Ota;Q;?AEggHE3kTCGz zg_(G~Ghxpgd~lOY_xeVCiBwJS_8BRr*{-D zBI!>EehWBSdGRSPd@grg;{2B2@#SKaS{zRiBLf3t!GVO#9~j6@h|d1dz(7I5hWpCR zgndI0x}~{$*NfP;sW{B_ z26O#pV+@BlR#u4kwY_k&AZ!t3*FSvT*k zH210Ab1E(}9}v9Id)V|H$qkYx*}`HCc_Cr00Z0oa{Fxi9S0d8ir8|8;H-XOcsx9v1 zqM*z5JecmZAw1UPt{d30t{{=&#y8Y`iLqdPL1L*J3Ycah!`n=HA(QJFNGzqJ0FIX8 zs35TnY?iZ0OjuwPuoKI?!{(7;GqDUtD@ZJNw{-U(vyasetWRWwat{?GR=8Vs_qTMZ z!ZqtqzLLu`-N(doZ%_ZR<;%SZ8T2HUaE%3sA zUw40Ed9KIwC0q!;^jrj-#~g1y|}R7%&lk1e6}T=y{trRTYirBS-s4J#~)k1fo zAU{!nQMeTYpaGHkj>9lFSd~k2=wEDsFf2$ES*|_ia`-6H5?i+%OOaW=e$0R5#o|Tg zdABwtZnK<`mx7z(<2!S5z?}1rXsKLeR5@)B3;X14=C`CeTFeef>i~H za(CfbH3f-^_iBoO9!2v?xJYDgFbmBFnh0RprXxohavL!5^ka>|M2p#>LgFhUuy7S- ztn9=JG_zw8-N4O`;nvqgnm0dmq%hYsYmR_t^{LIwLd7p(&-GZX&BQRxCA)U_KV+CT zbIn6Wo^ADjhvruYrfSFsf?PjFHoSf6FvXlA^VI@mc!$Sw6E<&f3{#xp4X#0ccmVUl z>3xELhFL$?AFNuF3kiPciG-zq-#Z8a5SobXm^|Q&6a*aBjnj~TV-TG;FbGhrYczu{ z$U?Aevut4kK}w#sMQ#nuw0*uR;lLzfn*Q7d5=vgIvFcbEWof)ZtH02!!P-se4OIxH z^R7swZop9!s^+%|%86%2-f*t=7Vs7%c39Hb`r2K?w3j$tWy{62m_G{1ivGk3Z-3_+ ztfXemK;f}MxeDWU=P9*;HJzu_?mDH`>bscV={@S)iK_g?4XjR_HfR;^jLC|=eLXq-Mwz*YH{Rs1-r&R<79BfDsA=1tH56J)7jk39)S_{zdW z8Af^IyOcM9om{mtQI0mv?nEV$7P6ub<~IFUd@XCWx+$O&EiiMN`$0@$$h0FPDbwM8 zP;yBpGF-Bo+W1fvpf;50qBfN2rZ$x6aX*B)unxIiadepXWNqN8ICp%2JPmDof1|fzNiu@?w>x2A8NTHMkUQYv%b~ z#z)NWeJV@MFIQP=eg%5gD1KL}EH(H$m8Aw(q3w=&e(&ca=66_Ssrd&~mYQFUo;wu3 z52`FRxJG5E!L{y(((Hz{qxIw`9HE45edi%-8K;j*2%KbnGl2c0{4f?dby_uhOf2y{ zv;|xKEtGrsJjb#W!=dsUQ?qTHPxCys(hzB=N%uS^cHti%*+l)Z_41nC*!^GA ze~gau=;%?$m3Xtqu4_iI1-4-ejQ<{9>sXOuxV9XZ_%f9JdaS|q52cKyiu(Hh3%k literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 97328c2..92a5161 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,6 +1,7 @@ + + + diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePicker.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePicker.java index 68c1464..b350460 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePicker.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePicker.java @@ -16,6 +16,7 @@ import androidx.annotation.ColorInt; import androidx.annotation.DrawableRes; +import androidx.core.content.res.ResourcesCompat; import java.util.Date; @@ -28,7 +29,7 @@ import ir.hamsaa.persiandatepicker.view.PersianNumberPicker; -class PersianDatePicker extends LinearLayout { +public class PersianDatePicker extends LinearLayout { private PersianPickerDate persianDate; private int selectedMonth; @@ -47,7 +48,7 @@ class PersianDatePicker extends LinearLayout { private boolean displayDescription; private final TextView descriptionTextView; - private Typeface typeFace; + public static Typeface typeFace; private int dividerColor; private int yearRange; @@ -62,6 +63,13 @@ public PersianDatePicker(Context context, AttributeSet attrs) { public PersianDatePicker(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PersianDatePicker, 0, 0); + yearRange = a.getInteger(R.styleable.PersianDatePicker_yearRange, 10); + + typeFace = ResourcesCompat.getFont(context, a.getResourceId(R.styleable.PersianDatePicker_fontFamily, 0)); + + // inflate views View view = LayoutInflater.from(context).inflate(R.layout.sl_persian_date_picker, this); @@ -71,7 +79,6 @@ public PersianDatePicker(Context context, AttributeSet attrs, int defStyle) { dayNumberPicker = view.findViewById(R.id.dayNumberPicker); descriptionTextView = view.findViewById(R.id.descriptionTextView); - yearNumberPicker.setFormatter(new NumberPicker.Formatter() { @Override public String format(int i) { @@ -96,17 +103,6 @@ public String format(int i) { // init calendar persianDate = new PersianDateImpl(); - // update variables from xml - updateVariablesFromXml(context, attrs); - - // update view - updateViewData(); - } - - private void updateVariablesFromXml(Context context, AttributeSet attrs) { - - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PersianDatePicker, 0, 0); - yearRange = a.getInteger(R.styleable.PersianDatePicker_yearRange, 10); /* * Initializing yearNumberPicker min and max values If minYear and * maxYear attributes are not set, use (current year - 10) as min and @@ -132,6 +128,14 @@ private void updateVariablesFromXml(Context context, AttributeSet attrs) { maxYear = selectedYear + yearRange; } + if (a.hasValue(R.styleable.PersianDatePicker_background)) + setBackgroundDrawable(a.getResourceId(R.styleable.PersianDatePicker_background, 0)); + if (a.hasValue(R.styleable.PersianDatePicker_backgroundColor)) + setBackgroundColor(a.getColor(R.styleable.PersianDatePicker_backgroundColor, 0)); + + // update view + updateViewData(); + a.recycle(); } @@ -207,11 +211,11 @@ private void updateViewData() { dayNumberPicker.setTypeFace(typeFace); } - if (dividerColor > 0) { + setDividerColor(yearNumberPicker, dividerColor); setDividerColor(monthNumberPicker, dividerColor); setDividerColor(dayNumberPicker, dividerColor); - } + yearNumberPicker.setMinValue(minYear); yearNumberPicker.setMaxValue(maxYear); diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/view/PersianNumberPicker.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/view/PersianNumberPicker.java index 9fc7b12..631e705 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/view/PersianNumberPicker.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/view/PersianNumberPicker.java @@ -11,6 +11,7 @@ import java.util.ArrayList; import java.util.List; +import ir.hamsaa.persiandatepicker.PersianDatePicker; import ir.hamsaa.persiandatepicker.PersianDatePickerDialog; /** @@ -61,6 +62,8 @@ private void updateView(View view) { if (view instanceof TextView) { if (PersianDatePickerDialog.typeFace != null) ((TextView) view).setTypeface(PersianDatePickerDialog.typeFace); + if (PersianDatePicker.typeFace != null) + ((TextView) view).setTypeface(PersianDatePicker.typeFace); } } diff --git a/persiandatepicker/src/main/res/values/attrs.xml b/persiandatepicker/src/main/res/values/attrs.xml index e157b3e..e5d4175 100644 --- a/persiandatepicker/src/main/res/values/attrs.xml +++ b/persiandatepicker/src/main/res/values/attrs.xml @@ -10,7 +10,11 @@ + + + + \ No newline at end of file From 98fae3bc853410b5714e74e8dfc4120910ae0116 Mon Sep 17 00:00:00 2001 From: am3n Date: Fri, 21 Jan 2022 14:02:20 +0330 Subject: [PATCH 03/14] try to fix jitpack build error --- build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index c04d8a9..c573f47 100644 --- a/build.gradle +++ b/build.gradle @@ -2,13 +2,13 @@ buildscript { ext { - appCompat = '1.4.1' - material = '1.5.0' + appCompat = '1.3.1' + material = '1.4.0' persianDate = '1.3.4' libraryMinSdk = 14 - libraryTargetSdk = 31 - libraryCompileSdkVersion = 31 + libraryTargetSdk = 30 + libraryCompileSdkVersion = 30 } repositories { google() From 756d75dce28cf18124eababbc579edd7706fe399 Mon Sep 17 00:00:00 2001 From: Amirhosein Date: Wed, 26 Jan 2022 13:06:29 +0330 Subject: [PATCH 04/14] fix bug when show as dialog --- .../ir/hamsaa/persiandatepicker/PersianDatePicker.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePicker.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePicker.java index b350460..d5a03e6 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePicker.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePicker.java @@ -67,7 +67,8 @@ public PersianDatePicker(Context context, AttributeSet attrs, int defStyle) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PersianDatePicker, 0, 0); yearRange = a.getInteger(R.styleable.PersianDatePicker_yearRange, 10); - typeFace = ResourcesCompat.getFont(context, a.getResourceId(R.styleable.PersianDatePicker_fontFamily, 0)); + if (a.hasValue(R.styleable.PersianDatePicker_fontFamily)) + typeFace = ResourcesCompat.getFont(context, a.getResourceId(R.styleable.PersianDatePicker_fontFamily, 0)); // inflate views @@ -212,9 +213,9 @@ private void updateViewData() { } - setDividerColor(yearNumberPicker, dividerColor); - setDividerColor(monthNumberPicker, dividerColor); - setDividerColor(dayNumberPicker, dividerColor); + setDividerColor(yearNumberPicker, dividerColor); + setDividerColor(monthNumberPicker, dividerColor); + setDividerColor(dayNumberPicker, dividerColor); yearNumberPicker.setMinValue(minYear); From f57640f209a97d287913cf0987ca9b09291b659f Mon Sep 17 00:00:00 2001 From: Amirhosein Date: Wed, 30 Mar 2022 13:23:40 +0430 Subject: [PATCH 05/14] fetch upstream --- README.md | 2 +- app/build.gradle | 2 - app/src/main/AndroidManifest.xml | 3 +- app/src/main/java/ir/hamsaa/MainActivity.java | 14 +- build.gradle | 10 +- gradle/wrapper/gradle-wrapper.properties | 6 +- persiandatepicker/build.gradle | 4 +- .../persiandatepicker/PersianDatePicker.java | 15 +- .../PersianDatePickerDialog.java | 27 +- .../api/PersianPickerDate.java | 2 + .../date/PersianDateFixedLeapYear.java | 43 +++ .../date/PersianDateImpl.java | 22 +- .../util/PersianCalendar.java | 4 +- .../util/PersianCalendarConstants.java | 95 +++--- .../util/PersianCalendarUtils.java | 2 + .../util/PersianDateParser.java | 313 +++++++++--------- .../persiandatepicker/util/PersianHelper.java | 27 +- 17 files changed, 336 insertions(+), 255 deletions(-) create mode 100644 persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/date/PersianDateFixedLeapYear.java diff --git a/README.md b/README.md index 1a7bcde..3f53f41 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ allprojects { Step 2. Add the dependency ```groovy dependencies { - implementation 'com.github.aliab:Persian-Date-Picker-Dialog:1.7.1' + implementation 'com.github.aliab:Persian-Date-Picker-Dialog:1.8.0' } ``` diff --git a/app/build.gradle b/app/build.gradle index c8ce602..ea4dafe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,6 @@ android { dependencies { implementation project(":persiandatepicker") - implementation "androidx.appcompat:appcompat:$appCompat" - implementation "com.google.android.material:material:$material" } repositories { mavenCentral() diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0e1d640..8a63664 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,7 +8,8 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> - diff --git a/app/src/main/java/ir/hamsaa/MainActivity.java b/app/src/main/java/ir/hamsaa/MainActivity.java index 5d1237f..e4a8397 100644 --- a/app/src/main/java/ir/hamsaa/MainActivity.java +++ b/app/src/main/java/ir/hamsaa/MainActivity.java @@ -10,13 +10,12 @@ import androidx.appcompat.app.AppCompatActivity; - import ir.hamsaa.persiandatepicker.Listener; import ir.hamsaa.persiandatepicker.PersianDatePickerDialog; import ir.hamsaa.persiandatepicker.api.PersianPickerDate; import ir.hamsaa.persiandatepicker.api.PersianPickerListener; +import ir.hamsaa.persiandatepicker.date.PersianDateImpl; import ir.hamsaa.persiandatepicker.util.PersianCalendar; -import ir.hamsaa.persiandatepicker.util.PersianCalendarUtils; public class MainActivity extends AppCompatActivity { @@ -43,11 +42,12 @@ public void showCalendar(View v) { .setTodayButtonVisible(true) .setMinYear(1300) .setAllButtonsTextSize(12) - .setMaxYear(PersianDatePickerDialog.THIS_YEAR) + .setMaxYear(1500) .setInitDate(1370, 3, 13) .setActionTextColor(Color.GRAY) .setTypeFace(typeface) - .setTitleType(PersianDatePickerDialog.WEEKDAY_DAY_MONTH_YEAR) +// .setShowDayPicker(false) + .setTitleType(PersianDatePickerDialog.DAY_MONTH_YEAR) .setShowInBottomSheet(true) .setListener(new PersianPickerListener() { @Override @@ -56,7 +56,7 @@ public void onDateSelected(PersianPickerDate persianPickerDate) { Log.d(TAG, "onDateSelected: " + persianPickerDate.getGregorianDate());//Mon Jun 03 10:57:28 GMT+04:30 1991 Log.d(TAG, "onDateSelected: " + persianPickerDate.getPersianLongDate());// دوشنبه 13 خرداد 1370 Log.d(TAG, "onDateSelected: " + persianPickerDate.getPersianMonthName());//خرداد - Log.d(TAG, "onDateSelected: " + PersianCalendarUtils.isPersianLeapYear(persianPickerDate.getPersianYear()));//true + Log.d(TAG, "onDateSelected: " + PersianDateImpl.isLeapYear(persianPickerDate.getPersianYear()));//true Toast.makeText(MainActivity.this, persianPickerDate.getPersianYear() + "/" + persianPickerDate.getPersianMonth() + "/" + persianPickerDate.getPersianDay(), Toast.LENGTH_SHORT).show(); } @@ -88,7 +88,9 @@ public void showCalendarInDarkMode(View v) { .setTitleColor(Color.WHITE) .setActionTextColor(Color.RED) .setPickerBackgroundDrawable(R.drawable.darkmode_bg) - .setTitleType(PersianDatePickerDialog.DAY_MONTH_YEAR) + .setTitleType(PersianDatePickerDialog.MONTH_YEAR) + .setShowDayPicker(false) + .setCancelable(false) .setListener(new Listener() { @Override diff --git a/build.gradle b/build.gradle index c573f47..1afece5 100644 --- a/build.gradle +++ b/build.gradle @@ -2,20 +2,20 @@ buildscript { ext { - appCompat = '1.3.1' - material = '1.4.0' + appCompat = '1.4.1' + material = '1.5.0' persianDate = '1.3.4' libraryMinSdk = 14 - libraryTargetSdk = 30 - libraryCompileSdkVersion = 30 + libraryTargetSdk = 31 + libraryCompileSdkVersion = 31 } repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.2' + classpath 'com.android.tools.build:gradle:7.1.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2f3a207..8ec5f13 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Apr 23 19:11:17 IRDT 2021 +#Sun Mar 06 09:14:05 IRST 2022 distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip +zipStoreBase=GRADLE_USER_HOME diff --git a/persiandatepicker/build.gradle b/persiandatepicker/build.gradle index d8f87f8..4cbee9e 100644 --- a/persiandatepicker/build.gradle +++ b/persiandatepicker/build.gradle @@ -22,8 +22,8 @@ android { } dependencies { - implementation "androidx.appcompat:appcompat:$appCompat" - implementation "com.google.android.material:material:$material" + api "androidx.appcompat:appcompat:$appCompat" + api "com.google.android.material:material:$material" implementation "com.github.samanzamani:PersianDate:$persianDate" } diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePicker.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePicker.java index d5a03e6..63993e2 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePicker.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePicker.java @@ -24,7 +24,6 @@ import ir.hamsaa.persiandatepicker.date.PersianDateImpl; import ir.hamsaa.persiandatepicker.util.PersianCalendar; import ir.hamsaa.persiandatepicker.util.PersianCalendarConstants; -import ir.hamsaa.persiandatepicker.util.PersianCalendarUtils; import ir.hamsaa.persiandatepicker.util.PersianHelper; import ir.hamsaa.persiandatepicker.view.PersianNumberPicker; @@ -172,6 +171,16 @@ public void setMinYear(int minYear) { updateViewData(); } + public void setDayVisibility(boolean visibility) { + if (visibility) { + dayNumberPicker.setVisibility(View.VISIBLE); + }else { + dayNumberPicker.setVisibility(View.GONE); + } + + invalidate(); + } + public void setTypeFace(Typeface typeFace) { this.typeFace = typeFace; updateViewData(); @@ -259,7 +268,7 @@ private void updateViewData() { if (selectedMonth > 6 && selectedMonth < 12 && selectedDay == 31) { selectedDay = 30; } else { - boolean isLeapYear = PersianCalendarUtils.isPersianLeapYear(selectedYear); + boolean isLeapYear = PersianDateImpl.isLeapYear(selectedYear); if (isLeapYear && selectedDay == 31) { selectedDay = 30; } else if (selectedDay > 29) { @@ -281,7 +290,7 @@ private void updateViewData() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { int year = yearNumberPicker.getValue(); - boolean isLeapYear = PersianCalendarUtils.isPersianLeapYear(year); + boolean isLeapYear = PersianDateImpl.isLeapYear(year); int month = monthNumberPicker.getValue(); int day = dayNumberPicker.getValue(); diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePickerDialog.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePickerDialog.java index 3b5570b..1755ea8 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePickerDialog.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/PersianDatePickerDialog.java @@ -39,8 +39,9 @@ public class PersianDatePickerDialog { public static final int NO_TITLE = 0; public static final int DAY_MONTH_YEAR = 1; public static final int WEEKDAY_DAY_MONTH_YEAR = 2; + public static final int MONTH_YEAR = 3; - private Context context; + private final Context context; private String positiveButtonString = "تایید"; private String negativeButtonString = "انصراف"; private Listener listener; @@ -49,7 +50,7 @@ public class PersianDatePickerDialog { private int maxMonth = 0; private int maxDay = 0; private int minYear = 0; - private PersianPickerDate initDate = new PersianDateImpl(); + private final PersianPickerDate initDate = new PersianDateImpl(); public static Typeface typeFace; private String todayButtonString = "امروز"; private boolean todayButtonVisibility = false; @@ -61,6 +62,7 @@ public class PersianDatePickerDialog { private int titleColor = Color.parseColor("#111111"); private boolean cancelable = true; private boolean forceMode; + private boolean isShowDayPicker = true; private int pickerBackgroundColor; private int pickerBackgroundDrawable; private int titleType = 0; @@ -180,6 +182,11 @@ public PersianDatePickerDialog setTodayButtonResource(@StringRes int todayButton return this; } + public PersianDatePickerDialog setShowDayPicker(boolean showDayPicker) { + this.isShowDayPicker = showDayPicker; + return this; + } + public PersianDatePickerDialog setTodayTextSize(int sizeInt) { this.todayTextSize = sizeInt; return this; @@ -260,6 +267,7 @@ public PersianDatePickerDialog setShowInBottomSheet(boolean b) { public void show() { + PersianDateImpl persianDate = new PersianDateImpl(); View v = View.inflate(context, R.layout.dialog_picker, null); final PersianDatePicker datePickerView = v.findViewById(R.id.datePicker); final TextView dateText = v.findViewById(R.id.dateText); @@ -270,7 +278,7 @@ public void show() { container.setBackgroundColor(backgroundColor); dateText.setTextColor(titleColor); - + datePickerView.setDayVisibility(isShowDayPicker); if (pickerBackgroundColor != 0) { datePickerView.setBackgroundColor(pickerBackgroundColor); @@ -281,28 +289,28 @@ public void show() { if (maxYear > 0) { datePickerView.setMaxYear(maxYear); } else if (maxYear == THIS_YEAR) { - maxYear = new PersianDateImpl().getPersianYear(); + maxYear = persianDate.getPersianYear(); datePickerView.setMaxYear(maxYear); } if (maxMonth > 0) { datePickerView.setMaxMonth(maxMonth); } else if (maxMonth == THIS_MONTH) { - maxMonth = new PersianDateImpl().getPersianMonth(); + maxMonth = persianDate.getPersianMonth(); datePickerView.setMaxMonth(maxMonth); } if (maxDay > 0) { datePickerView.setMaxDay(maxDay); } else if (maxDay == THIS_DAY) { - maxDay = new PersianDateImpl().getPersianDay(); + maxDay = persianDate.getPersianDay(); datePickerView.setMaxDay(maxDay); } if (minYear > 0) { datePickerView.setMinYear(minYear); } else if (minYear == THIS_YEAR) { - minYear = new PersianDateImpl().getPersianYear(); + minYear = persianDate.getPersianYear(); datePickerView.setMinYear(minYear); } @@ -437,6 +445,11 @@ private void updateView(TextView dateText, PersianPickerDate persianDate) { persianDate.getPersianDay() + " " + persianDate.getPersianMonthName() + " " + persianDate.getPersianYear(); + dateText.setText(PersianHelper.toPersianNumber(date)); + break; + case MONTH_YEAR: + date = persianDate.getPersianMonthName() + " " + + persianDate.getPersianYear(); dateText.setText(PersianHelper.toPersianNumber(date)); break; diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/api/PersianPickerDate.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/api/PersianPickerDate.java index 3c80393..7cc4e23 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/api/PersianPickerDate.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/api/PersianPickerDate.java @@ -37,4 +37,6 @@ public interface PersianPickerDate { long getTimestamp(); + boolean isLeapYear(); + } diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/date/PersianDateFixedLeapYear.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/date/PersianDateFixedLeapYear.java new file mode 100644 index 0000000..6832067 --- /dev/null +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/date/PersianDateFixedLeapYear.java @@ -0,0 +1,43 @@ +package ir.hamsaa.persiandatepicker.date; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import saman.zamani.persiandate.PersianDate; + +public class PersianDateFixedLeapYear extends PersianDate { + + /** + * Thanks to Persian Calendar Project + */ + private final List leapYears = Arrays.asList( + 1210, 1214, 1218, 1222, 1226, 1230, 1234, 1238, 1243, 1247, 1251, 1255, 1259, 1263, + 1267, 1271, 1276, 1280, 1284, 1288, 1292, 1296, 1300, 1304, 1309, 1313, 1317, 1321, + 1325, 1329, 1333, 1337, 1342, 1346, 1350, 1354, 1358, 1362, 1366, 1370, 1375, 1379, + 1383, 1387, 1391, 1395, 1399, 1403, 1408, 1412, 1416, 1420, 1424, 1428, 1432, 1436, + 1441, 1445, 1449, 1453, 1457, 1461, 1465, 1469, 1474, 1478, 1482, 1486, 1490, 1494, + 1498); + + + public PersianDateFixedLeapYear() { + } + + public PersianDateFixedLeapYear(Long timeInMilliSecond) { + super(timeInMilliSecond); + } + + public PersianDateFixedLeapYear(Date date) { + super(date); + } + + @Override + public boolean isLeap(int year) { + if (year > 1500) { + return super.isLeap(year); + } + return leapYears.contains(year); + } + + +} diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/date/PersianDateImpl.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/date/PersianDateImpl.java index 27117ea..4268a08 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/date/PersianDateImpl.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/date/PersianDateImpl.java @@ -3,33 +3,32 @@ import java.util.Date; import ir.hamsaa.persiandatepicker.api.PersianPickerDate; -import saman.zamani.persiandate.PersianDate; public class PersianDateImpl implements PersianPickerDate { - private PersianDate persianDate; + private PersianDateFixedLeapYear persianDate; public PersianDateImpl() { - persianDate = new PersianDate(); + persianDate = new PersianDateFixedLeapYear(); } @Override public void setDate(Long timestamp) { - persianDate = new PersianDate(timestamp); + persianDate = new PersianDateFixedLeapYear(timestamp); } @Override public void setDate(Date date) { - persianDate = new PersianDate(date); + persianDate = new PersianDateFixedLeapYear(date); } @Override public void setDate(int persianYear, int persianMonth, int persianDay) { - try{ + try { persianDate.setShYear(persianYear); persianDate.setShMonth(persianMonth); persianDate.setShDay(persianDay); - }catch (Exception e){ + } catch (Exception e) { e.printStackTrace(); } } @@ -93,4 +92,13 @@ public Date getGregorianDate() { public long getTimestamp() { return persianDate.getTime(); } + + @Override + public boolean isLeapYear() { + return persianDate.isLeap(); + } + + public static boolean isLeapYear(int year) { + return new PersianDateFixedLeapYear().isLeap(year); + } } diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianCalendar.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianCalendar.java index ab90ad9..f5a9e0f 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianCalendar.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianCalendar.java @@ -22,6 +22,8 @@ import java.util.Locale; import java.util.TimeZone; +import ir.hamsaa.persiandatepicker.date.PersianDateImpl; + /** * * Persian(Shamsi) calendar @@ -175,7 +177,7 @@ protected void calculatePersianDate() { */ public boolean isPersianLeapYear() { // calculatePersianDate(); - return PersianCalendarUtils.isPersianLeapYear(this.persianYear); + return PersianDateImpl.isLeapYear(this.persianYear); } /** diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianCalendarConstants.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianCalendarConstants.java index 976fa6d..3d5d9f8 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianCalendarConstants.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianCalendarConstants.java @@ -1,64 +1,65 @@ /** * Persian Calendar see: http://code.google.com/p/persian-calendar/ - Copyright (C) 2012 Mortezaadi@gmail.com - PersianCalendarConstants.java - - Persian Calendar is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + * Copyright (C) 2012 Mortezaadi@gmail.com + * PersianCalendarConstants.java + *

+ * Persian Calendar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package ir.hamsaa.persiandatepicker.util; /** - * + * * @author Morteza contact: Mortezaadi@gmail.com * @version 1.0 */ +@Deprecated public class PersianCalendarConstants { - // 00:00:00 UTC (Gregorian) Julian day 0, - // 0 milliseconds since 1970-01-01 - public static final long MILLIS_JULIAN_EPOCH = -210866803200000L; - // Milliseconds of a day calculated by 24L(hours) * 60L(minutes) * - // 60L(seconds) * 1000L(mili); - public static final long MILLIS_OF_A_DAY = 86400000L; + // 00:00:00 UTC (Gregorian) Julian day 0, + // 0 milliseconds since 1970-01-01 + public static final long MILLIS_JULIAN_EPOCH = -210866803200000L; + // Milliseconds of a day calculated by 24L(hours) * 60L(minutes) * + // 60L(seconds) * 1000L(mili); + public static final long MILLIS_OF_A_DAY = 86400000L; - /** - * The JDN of 1 Farvardin 1; Equivalent to March 19, 622 A.D. - */ - public static final long PERSIAN_EPOCH = 1948321; + /** + * The JDN of 1 Farvardin 1; Equivalent to March 19, 622 A.D. + */ + public static final long PERSIAN_EPOCH = 1948321; - public static final String[] persianMonthNames = { "\u0641\u0631\u0648\u0631\u062f\u06cc\u0646", // Farvardin - "\u0627\u0631\u062f\u06cc\u0628\u0647\u0634\u062a", // Ordibehesht - "\u062e\u0631\u062f\u0627\u062f", // Khordad - "\u062a\u06cc\u0631", // Tir - "\u0645\u0631\u062f\u0627\u062f", // Mordad - "\u0634\u0647\u0631\u06cc\u0648\u0631", // Shahrivar - "\u0645\u0647\u0631", // Mehr - "\u0622\u0628\u0627\u0646", // Aban - "\u0622\u0630\u0631", // Azar - "\u062f\u06cc", // Dey - "\u0628\u0647\u0645\u0646", // Bahman - "\u0627\u0633\u0641\u0646\u062f" // Esfand - }; + public static final String[] persianMonthNames = {"\u0641\u0631\u0648\u0631\u062f\u06cc\u0646", // Farvardin + "\u0627\u0631\u062f\u06cc\u0628\u0647\u0634\u062a", // Ordibehesht + "\u062e\u0631\u062f\u0627\u062f", // Khordad + "\u062a\u06cc\u0631", // Tir + "\u0645\u0631\u062f\u0627\u062f", // Mordad + "\u0634\u0647\u0631\u06cc\u0648\u0631", // Shahrivar + "\u0645\u0647\u0631", // Mehr + "\u0622\u0628\u0627\u0646", // Aban + "\u0622\u0630\u0631", // Azar + "\u062f\u06cc", // Dey + "\u0628\u0647\u0645\u0646", // Bahman + "\u0627\u0633\u0641\u0646\u062f" // Esfand + }; - public static final String[] persianWeekDays = { "\u0634\u0646\u0628\u0647", // Shanbeh - "\u06cc\u06a9\u200c\u0634\u0646\u0628\u0647", // Yekshanbeh - "\u062f\u0648\u0634\u0646\u0628\u0647", // Doshanbeh - "\u0633\u0647\u200c\u0634\u0646\u0628\u0647", // Sehshanbeh - "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647", // Chaharshanbeh - "\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647", // Panjshanbeh - "\u062c\u0645\u0639\u0647" // jome - }; + public static final String[] persianWeekDays = {"\u0634\u0646\u0628\u0647", // Shanbeh + "\u06cc\u06a9\u200c\u0634\u0646\u0628\u0647", // Yekshanbeh + "\u062f\u0648\u0634\u0646\u0628\u0647", // Doshanbeh + "\u0633\u0647\u200c\u0634\u0646\u0628\u0647", // Sehshanbeh + "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647", // Chaharshanbeh + "\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647", // Panjshanbeh + "\u062c\u0645\u0639\u0647" // jome + }; } diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianCalendarUtils.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianCalendarUtils.java index 4c53d77..1a31851 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianCalendarUtils.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianCalendarUtils.java @@ -18,6 +18,7 @@ */ package ir.hamsaa.persiandatepicker.util; + /** * algorithms for converting Julian days to the Persian calendar, and vice versa * are adopted from . + * Copyright (C) 2012 Mortezaadi@gmail.com + * PersianDateParser.java + *

+ * Persian Calendar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package ir.hamsaa.persiandatepicker.util; +import ir.hamsaa.persiandatepicker.date.PersianDateImpl; + /** * Parses text from the beginning of the given string to produce a * PersianCalendar. - * + * *

* See the {@link #getPersianDate()} method for more information on date * parsing. - * + * *

  *                Example
- *                     
+ *
  *  {@code
  *    PersianCalendar pCal =
- *     new PersianDateParser("1361/3/1").getPersianDate();             
+ *     new PersianDateParser("1361/3/1").getPersianDate();
  *  }
  * 
- * + * * @author Morteza contact: Mortezaadi@gmail.com * @version 1.0 */ +@Deprecated public class PersianDateParser { - private String dateString; - private String delimiter = "/"; - - /** - *
-	 * construct parser with date string assigned
-	 * the default delimiter is '/'.
-	 * 
-	 * To assign deferment delimiter use:
-	 * {@link #PersianDateParser(String dateString, String delimiter)}
-	 * 
-	 *                     Example
-	 *                     
-	 *  {@code
-	 *    PersianCalendar pCal =
-	 *     new PersianDateParser("1361/3/1").getPersianDate();             
-	 *  }
-	 * 
- * - * @param dateString - */ - public PersianDateParser(String dateString) { - this.dateString = dateString; - } - - /** - *
-	 * construct parser with date string assigned
-	 * the default delimiter is '/'. with this constructor
-	 * you can set different delimiter to parse the date
-	 * based on this delimiter.
-	 * see also:
-	 * {@link #PersianDateParser(String dateString)}
-	 * 
-	 *                     Example
-	 *                     
-	 *  {@code
-	 *    PersianCalendar pCal =
-	 *     new PersianDateParser("1361-3-1","-").getPersianDate();             
-	 *  }
-	 * 
- * - * @param dateString - * @param delimiter - */ - public PersianDateParser(String dateString, String delimiter) { - this(dateString); - this.delimiter = delimiter; - } - - /** - * Produce the PersianCalendar object from given DateString throws Exception - * if couldn't parse the text. - * - * @return PersianCalendar object - * @exception RuntimeException - */ - public PersianCalendar getPersianDate() { - - checkDateStringInitialValidation(); - - String tokens[] = splitDateString(normalizeDateString(dateString)); - int year = Integer.parseInt(tokens[0]); - int month = Integer.parseInt(tokens[1]); - int day = Integer.parseInt(tokens[2]); - - checkPersianDateValidation(year, month, day); - - PersianCalendar pCal = new PersianCalendar(); - pCal.setPersianDate(year, month, day); - - return pCal; - } - - /** - * validate the given date - * - * @param year - * @param month - * @param day - */ - private void checkPersianDateValidation(int year, int month, int day) { - if (year < 1) - throw new RuntimeException("year is not valid"); - if (month < 1 || month > 12) - throw new RuntimeException("month is not valid"); - if (day < 1 || day > 31) - throw new RuntimeException("day is not valid"); - if (month > 6 && day == 31) - throw new RuntimeException("day is not valid"); - if (month == 12 && day == 30 && !PersianCalendarUtils.isPersianLeapYear(year)) - throw new RuntimeException("day is not valid " + year + " is not a leap year"); - } - - /** - * planned for further calculation before parsing the text - * - * @param dateString - * @return - */ - private String normalizeDateString(String dateString) { - // dateString = dateString.replace("-", delimiter); - return dateString; - } - - private String[] splitDateString(String dateString) { - String tokens[] = dateString.split(delimiter); - if (tokens.length != 3) - throw new RuntimeException("wrong date:" + dateString + " is not a Persian Date or can not be parsed"); - return tokens; - } - - private void checkDateStringInitialValidation() { - if (dateString == null) - throw new RuntimeException("input didn't assing please use setDateString()"); - // if(dateString.length()>10) - // throw new RuntimeException("wrong date:" + dateString + - // " is not a Persian Date or can not be parsed" ); - } - - public String getDateString() { - return dateString; - } - - public void setDateString(String dateString) { - this.dateString = dateString; - } - - public String getDelimiter() { - return delimiter; - } - - public void setDelimiter(String delimiter) { - this.delimiter = delimiter; - } + private String dateString; + private String delimiter = "/"; + + /** + *
+     * construct parser with date string assigned
+     * the default delimiter is '/'.
+     *
+     * To assign deferment delimiter use:
+     * {@link #PersianDateParser(String dateString, String delimiter)}
+     *
+     *                     Example
+     *
+     *  {@code
+     *    PersianCalendar pCal =
+     *     new PersianDateParser("1361/3/1").getPersianDate();
+     *  }
+     * 
+ * + * @param dateString + */ + public PersianDateParser(String dateString) { + this.dateString = dateString; + } + + /** + *
+     * construct parser with date string assigned
+     * the default delimiter is '/'. with this constructor
+     * you can set different delimiter to parse the date
+     * based on this delimiter.
+     * see also:
+     * {@link #PersianDateParser(String dateString)}
+     *
+     *                     Example
+     *
+     *  {@code
+     *    PersianCalendar pCal =
+     *     new PersianDateParser("1361-3-1","-").getPersianDate();
+     *  }
+     * 
+ * + * @param dateString + * @param delimiter + */ + public PersianDateParser(String dateString, String delimiter) { + this(dateString); + this.delimiter = delimiter; + } + + /** + * Produce the PersianCalendar object from given DateString throws Exception + * if couldn't parse the text. + * + * @return PersianCalendar object + * @exception RuntimeException + */ + public PersianCalendar getPersianDate() { + + checkDateStringInitialValidation(); + + String tokens[] = splitDateString(normalizeDateString(dateString)); + int year = Integer.parseInt(tokens[0]); + int month = Integer.parseInt(tokens[1]); + int day = Integer.parseInt(tokens[2]); + + checkPersianDateValidation(year, month, day); + + PersianCalendar pCal = new PersianCalendar(); + pCal.setPersianDate(year, month, day); + + return pCal; + } + + /** + * validate the given date + * + * @param year + * @param month + * @param day + */ + private void checkPersianDateValidation(int year, int month, int day) { + if (year < 1) + throw new RuntimeException("year is not valid"); + if (month < 1 || month > 12) + throw new RuntimeException("month is not valid"); + if (day < 1 || day > 31) + throw new RuntimeException("day is not valid"); + if (month > 6 && day == 31) + throw new RuntimeException("day is not valid"); + if (month == 12 && day == 30 && !PersianDateImpl.isLeapYear(year)) + throw new RuntimeException("day is not valid " + year + " is not a leap year"); + } + + /** + * planned for further calculation before parsing the text + * + * @param dateString + * @return + */ + private String normalizeDateString(String dateString) { + // dateString = dateString.replace("-", delimiter); + return dateString; + } + + private String[] splitDateString(String dateString) { + String tokens[] = dateString.split(delimiter); + if (tokens.length != 3) + throw new RuntimeException("wrong date:" + dateString + " is not a Persian Date or can not be parsed"); + return tokens; + } + + private void checkDateStringInitialValidation() { + if (dateString == null) + throw new RuntimeException("input didn't assing please use setDateString()"); + // if(dateString.length()>10) + // throw new RuntimeException("wrong date:" + dateString + + // " is not a Persian Date or can not be parsed" ); + } + + public String getDateString() { + return dateString; + } + + public void setDateString(String dateString) { + this.dateString = dateString; + } + + public String getDelimiter() { + return delimiter; + } + + public void setDelimiter(String delimiter) { + this.delimiter = delimiter; + } } diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianHelper.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianHelper.java index 7f56c76..31ab0f3 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianHelper.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianHelper.java @@ -1,36 +1,33 @@ package ir.hamsaa.persiandatepicker.util; -/** - * Created by sajjad on 01/18/2016. - */ public class PersianHelper { - private static char[] persianNumbers = new char[]{'۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'}; - private static char[] englishNumbers = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + private static final char[] persianNumbers = new char[]{'۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'}; + private static final char[] englishNumbers = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; public static String toPersianNumber(String text) { if (text.isEmpty()) return ""; - String out = ""; + StringBuilder out = new StringBuilder(); int length = text.length(); for (int i = 0; i < length; i++) { char c = text.charAt(i); if ('0' <= c && c <= '9') { int number = Integer.parseInt(String.valueOf(c)); - out += persianNumbers[number]; + out.append(persianNumbers[number]); } else if (c == '٫') { - out += '،'; + out.append('،'); } else { - out += c; + out.append(c); } } - return out; + return out.toString(); } public static String toEnglishNumber(String text) { if (text.isEmpty()) return ""; - String out = ""; + StringBuilder out = new StringBuilder(); int length = text.length(); for (int i = 0; i < length; i++) { @@ -38,16 +35,16 @@ public static String toEnglishNumber(String text) { int charPos; if ((charPos = hasCharachter(c)) != -1) { - out += englishNumbers[charPos]; + out.append(englishNumbers[charPos]); } else if (c == '،') { - out += '٫'; + out.append('٫'); } else { - out += c; + out.append(c); } } - return out; + return out.toString(); } private static int hasCharachter(char c) { From 0c71ed1c27cdf4a78335b61cf5453d0bda096f4b Mon Sep 17 00:00:00 2001 From: Amirhosein Date: Wed, 30 Mar 2022 14:11:22 +0430 Subject: [PATCH 06/14] fix gradle issues --- app/build.gradle | 5 +++++ persiandatepicker/build.gradle | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index ea4dafe..e788826 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -19,7 +19,12 @@ android { } dependencies { + + implementation "androidx.appcompat:appcompat:$appCompat" + implementation "com.google.android.material:material:$material" + implementation project(":persiandatepicker") + } repositories { mavenCentral() diff --git a/persiandatepicker/build.gradle b/persiandatepicker/build.gradle index 4cbee9e..89ae061 100644 --- a/persiandatepicker/build.gradle +++ b/persiandatepicker/build.gradle @@ -22,8 +22,7 @@ android { } dependencies { - api "androidx.appcompat:appcompat:$appCompat" - api "com.google.android.material:material:$material" + implementation "androidx.appcompat:appcompat:$appCompat" + implementation "com.google.android.material:material:$material" implementation "com.github.samanzamani:PersianDate:$persianDate" - } From d36cfba81794106f66577bcd431c2380bfcb829b Mon Sep 17 00:00:00 2001 From: Amirhosein Date: Wed, 30 Mar 2022 14:57:37 +0430 Subject: [PATCH 07/14] add persian date --- app/src/main/java/ir/hamsaa/MainActivity.java | 23 +++++++++++++++++++ persiandatepicker/build.gradle | 2 +- .../api/PersianPickerDate.java | 4 ++++ .../date/PersianDateImpl.java | 5 ++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/ir/hamsaa/MainActivity.java b/app/src/main/java/ir/hamsaa/MainActivity.java index e4a8397..b59ac83 100644 --- a/app/src/main/java/ir/hamsaa/MainActivity.java +++ b/app/src/main/java/ir/hamsaa/MainActivity.java @@ -10,12 +10,16 @@ import androidx.appcompat.app.AppCompatActivity; +import java.text.ParseException; + import ir.hamsaa.persiandatepicker.Listener; import ir.hamsaa.persiandatepicker.PersianDatePickerDialog; import ir.hamsaa.persiandatepicker.api.PersianPickerDate; import ir.hamsaa.persiandatepicker.api.PersianPickerListener; +import ir.hamsaa.persiandatepicker.date.PersianDateFixedLeapYear; import ir.hamsaa.persiandatepicker.date.PersianDateImpl; import ir.hamsaa.persiandatepicker.util.PersianCalendar; +import saman.zamani.persiandate.PersianDateFormat; public class MainActivity extends AppCompatActivity { @@ -28,6 +32,25 @@ public class MainActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + + + PersianDateFixedLeapYear persianDate = new PersianDateFixedLeapYear(); + Log.d(TAG, "today: " + persianDate.getShDay()); + persianDate.addDay(1); + Log.d(TAG, "tomorrow: " + persianDate.getShDay()); + + + // format `persianDate` + Log.d(TAG, PersianDateFormat.format(persianDate, "Y/m/d")); + + // format string persian date + try { + Log.d(TAG, PersianDateFormat.format(new PersianDateFormat("yyyy/MM/dd").parse("1401/03/16"), "y-m-d")); + } catch (ParseException e) { + e.printStackTrace(); + } + + } diff --git a/persiandatepicker/build.gradle b/persiandatepicker/build.gradle index 89ae061..d0fd22c 100644 --- a/persiandatepicker/build.gradle +++ b/persiandatepicker/build.gradle @@ -24,5 +24,5 @@ android { dependencies { implementation "androidx.appcompat:appcompat:$appCompat" implementation "com.google.android.material:material:$material" - implementation "com.github.samanzamani:PersianDate:$persianDate" + api "com.github.samanzamani:PersianDate:$persianDate" } diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/api/PersianPickerDate.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/api/PersianPickerDate.java index 7cc4e23..6bf68e4 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/api/PersianPickerDate.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/api/PersianPickerDate.java @@ -2,6 +2,8 @@ import java.util.Date; +import ir.hamsaa.persiandatepicker.date.PersianDateFixedLeapYear; + public interface PersianPickerDate { void setDate(Long timestamp); @@ -10,6 +12,8 @@ public interface PersianPickerDate { void setDate(int persianYear, int persianMonth, int persianDay); + PersianDateFixedLeapYear getPersianDate(); + int getPersianYear(); int getPersianMonth(); diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/date/PersianDateImpl.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/date/PersianDateImpl.java index 4268a08..22e5d76 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/date/PersianDateImpl.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/date/PersianDateImpl.java @@ -33,6 +33,11 @@ public void setDate(int persianYear, int persianMonth, int persianDay) { } } + @Override + public PersianDateFixedLeapYear getPersianDate() { + return persianDate; + } + @Override public int getPersianYear() { return persianDate.getShYear(); From 1d1d31999dac2ea4e5a8217111c94e9f8a247764 Mon Sep 17 00:00:00 2001 From: Amirhosein Date: Tue, 19 Apr 2022 17:07:26 +0430 Subject: [PATCH 08/14] add persian date default format & parser methods --- app/src/main/java/ir/hamsaa/MainActivity.java | 1 - .../util/PersianDateHelper.java | 44 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java diff --git a/app/src/main/java/ir/hamsaa/MainActivity.java b/app/src/main/java/ir/hamsaa/MainActivity.java index b59ac83..b69864e 100644 --- a/app/src/main/java/ir/hamsaa/MainActivity.java +++ b/app/src/main/java/ir/hamsaa/MainActivity.java @@ -113,7 +113,6 @@ public void showCalendarInDarkMode(View v) { .setPickerBackgroundDrawable(R.drawable.darkmode_bg) .setTitleType(PersianDatePickerDialog.MONTH_YEAR) .setShowDayPicker(false) - .setCancelable(false) .setListener(new Listener() { @Override diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java new file mode 100644 index 0000000..d62b39f --- /dev/null +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java @@ -0,0 +1,44 @@ +package ir.hamsaa.persiandatepicker.util; + +import saman.zamani.persiandate.PersianDate; +import saman.zamani.persiandate.PersianDateFormat; + +public class PersianDateHelper { + + public boolean isValidDate(String date) { + try { + return !parseAndFormatDate(date).isEmpty(); + } catch (Throwable ignore) { + + } + return false; + } + + public String parseAndFormatDate(String date) { + try { + return PersianDateFormat.format(new PersianDateFormat("yyyy/MM/dd").parse(date), "Y/m/d"); + } catch (Throwable ignore) { + + } + return ""; + } + + public String formatDate(PersianDate date) { + try { + return PersianDateFormat.format(date, "Y/m/d"); + } catch (Throwable ignore) { + + } + return ""; + } + + public String formatTime(PersianDate time) { + try { + return PersianDateFormat.format(time, "H:i:s"); + } catch (Throwable ignore) { + + } + return ""; + } + +} From fac50bdaa9efae2801510463b0383aa38bc48f62 Mon Sep 17 00:00:00 2001 From: Amirhosein Date: Tue, 19 Apr 2022 17:38:08 +0430 Subject: [PATCH 09/14] minor fix --- .../hamsaa/persiandatepicker/util/PersianDateHelper.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java index d62b39f..6dbb4ee 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java @@ -5,7 +5,7 @@ public class PersianDateHelper { - public boolean isValidDate(String date) { + static public boolean isValidDate(String date) { try { return !parseAndFormatDate(date).isEmpty(); } catch (Throwable ignore) { @@ -14,7 +14,7 @@ public boolean isValidDate(String date) { return false; } - public String parseAndFormatDate(String date) { + static public String parseAndFormatDate(String date) { try { return PersianDateFormat.format(new PersianDateFormat("yyyy/MM/dd").parse(date), "Y/m/d"); } catch (Throwable ignore) { @@ -23,7 +23,7 @@ public String parseAndFormatDate(String date) { return ""; } - public String formatDate(PersianDate date) { + static public String formatDate(PersianDate date) { try { return PersianDateFormat.format(date, "Y/m/d"); } catch (Throwable ignore) { @@ -32,7 +32,7 @@ public String formatDate(PersianDate date) { return ""; } - public String formatTime(PersianDate time) { + static public String formatTime(PersianDate time) { try { return PersianDateFormat.format(time, "H:i:s"); } catch (Throwable ignore) { From da3fc4eeed6e9fd0f44b1553283e7c56fce4c605 Mon Sep 17 00:00:00 2001 From: Amirhosein Date: Tue, 19 Apr 2022 17:49:35 +0430 Subject: [PATCH 10/14] add date parse methods --- .../util/PersianDateHelper.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java index 6dbb4ee..2c52bcd 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java @@ -1,5 +1,7 @@ package ir.hamsaa.persiandatepicker.util; +import java.text.ParseException; + import saman.zamani.persiandate.PersianDate; import saman.zamani.persiandate.PersianDateFormat; @@ -14,9 +16,21 @@ static public boolean isValidDate(String date) { return false; } + static public PersianDate parseDate(String date) { + return parseDate(date, "yyyy/MM/dd"); + } + + static public PersianDate parseDate(String date, String pattern) { + try { + return new PersianDateFormat(pattern).parse(date); + } catch (ParseException ignore) { + } + return null; + } + static public String parseAndFormatDate(String date) { try { - return PersianDateFormat.format(new PersianDateFormat("yyyy/MM/dd").parse(date), "Y/m/d"); + return PersianDateFormat.format(parseDate(date), "Y/m/d"); } catch (Throwable ignore) { } From a9a3d78a07cc4bffd366be977738612ca2500d97 Mon Sep 17 00:00:00 2001 From: Amirhosein Date: Wed, 27 Apr 2022 22:34:57 +0430 Subject: [PATCH 11/14] add date parse methods --- .../persiandatepicker/util/PersianDateHelper.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java index 2c52bcd..5fb30ca 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java @@ -17,10 +17,18 @@ static public boolean isValidDate(String date) { } static public PersianDate parseDate(String date) { - return parseDate(date, "yyyy/MM/dd"); + return parseDateTime(date, "yyyy/MM/dd"); } - static public PersianDate parseDate(String date, String pattern) { + static public PersianDate parseTime(String date) { + return parseDateTime(date, "HH:mm:ss"); + } + + static public PersianDate parseDateTime(String datetime) { + return parseDateTime(datetime, "yyyy/MM/dd HH:mm:ss"); + } + + static public PersianDate parseDateTime(String date, String pattern) { try { return new PersianDateFormat(pattern).parse(date); } catch (ParseException ignore) { @@ -30,7 +38,7 @@ static public PersianDate parseDate(String date, String pattern) { static public String parseAndFormatDate(String date) { try { - return PersianDateFormat.format(parseDate(date), "Y/m/d"); + return PersianDateFormat.format(parseDateTime(date), "Y/m/d"); } catch (Throwable ignore) { } From 6eafea40a7f3c73a387210c7c8a0d24dd2614086 Mon Sep 17 00:00:00 2001 From: Amirhosein Date: Wed, 27 Apr 2022 22:37:15 +0430 Subject: [PATCH 12/14] update versions --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 1afece5..ed965dd 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { ext { appCompat = '1.4.1' material = '1.5.0' - persianDate = '1.3.4' + persianDate = '1.4.0' libraryMinSdk = 14 libraryTargetSdk = 31 @@ -15,7 +15,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.1.2' + classpath 'com.android.tools.build:gradle:7.1.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } From cff801fb52faec32245adc667d4709c1fe0a4508 Mon Sep 17 00:00:00 2001 From: Amirhosein Date: Fri, 29 Apr 2022 23:12:30 +0430 Subject: [PATCH 13/14] fix bug --- .../ir/hamsaa/persiandatepicker/util/PersianDateHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java index 5fb30ca..8e1814a 100644 --- a/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java +++ b/persiandatepicker/src/main/java/ir/hamsaa/persiandatepicker/util/PersianDateHelper.java @@ -38,7 +38,7 @@ static public PersianDate parseDateTime(String date, String pattern) { static public String parseAndFormatDate(String date) { try { - return PersianDateFormat.format(parseDateTime(date), "Y/m/d"); + return PersianDateFormat.format(parseDate(date), "Y/m/d"); } catch (Throwable ignore) { } From 7899138a564b96c9538d4c9fc101f3bcac077556 Mon Sep 17 00:00:00 2001 From: Amirhosein Date: Fri, 6 May 2022 20:57:09 +0430 Subject: [PATCH 14/14] fixed a bug on saman zamani library --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ed965dd..e6b114d 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { ext { appCompat = '1.4.1' material = '1.5.0' - persianDate = '1.4.0' + persianDate = '1.5.0' libraryMinSdk = 14 libraryTargetSdk = 31