All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.eloyzone.jalalicalendar.JalaliDateFormatter Maven / Gradle / Ivy

package com.github.eloyzone.jalalicalendar;

import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * Created By Eloy on 5/6/18.
 *
 * This class can be used for formatting an existing {@link JalaliDate}
 * 

* Note: for formatting gregorian date based on {@link java.time.LocalDate} you have to use {@link DateTimeFormatter}. * * @author Eloy (Elyas Hadizadeh Tasbiti) */ public class JalaliDateFormatter { private String pattern; private int formatLanguage; private JalaliDate jalaliDate; /** * a flag for configuring the language of formatting. * *

* you can call it from outside of the class for setting formatting language. usually can be used in constructor */ public static int FORMAT_IN_PERSIAN = 1; /** * a flag for configuring the language of formatting. * *

* you can call it from outside of the class for setting formatting language. usually can be used in constructor */ public static int FORMAT_IN_ENGLISH = 2; /** * constructor that sets english as a default formatting language. * * @param pattern desired pattern. */ public JalaliDateFormatter(String pattern) { this.pattern = pattern; this.formatLanguage = FORMAT_IN_ENGLISH; } /** * constructor that sets desired language for formatting * * @param pattern desired pattern. * @param formatLanguage shows the selected language which 1 is persian and 2 is english. */ public JalaliDateFormatter(String pattern, int formatLanguage) { this.pattern = pattern; this.formatLanguage = formatLanguage; } /** * Returns a string that shows given jalali date in a proper formatting, it first parses the given pattern and * creates some place holders for future values then it applies format. * * @param jalaliDate date that will be formatted in a proper way. * @return a formatted date in a string that can be persian or english */ public String format(JalaliDate jalaliDate) { this.jalaliDate = jalaliDate; parsePattern(pattern); String result = ""; if (formatLanguage == FORMAT_IN_PERSIAN && pattern.contains("M")) { for (int i = dateFormatterTemporalFields.size() - 1; i >= 0; i--) result = result + applyFormat(i); } else { for (int i = 0; i < dateFormatterTemporalFields.size(); i++) result = result + applyFormat(i); } if (formatLanguage == FORMAT_IN_PERSIAN) { char[] resultChars = result.toCharArray(); for (int i = 0; i < resultChars.length; i++) { resultChars[i] = replaceWithPersian(resultChars[i]); } result = String.valueOf(resultChars); } return result; } /* Creates string format of date based on list of temporal fields. */ private String applyFormat(int index) { String result = ""; String temp = ""; DateFormatterTemporalField dateFormatterTemporalField = dateFormatterTemporalFields.get(index); switch (dateFormatterTemporalField.getType()) { case DateFormatterTemporalField.YEAR_FIElD: if (dateFormatterTemporalField.getCount() == 2) { temp = jalaliDate.getYear() + ""; result = result + temp.substring(1, 3); } else { result = result + jalaliDate.getYear(); } break; case DateFormatterTemporalField.MONTH_FIElD: int monthValue = jalaliDate.getMonthPersian().getValue(); if (dateFormatterTemporalField.getCount() == 2) { if (monthValue < 10) { temp = "0"; } result = result + temp + monthValue; } else { if (monthValue < 10) { throw new IllegalArgumentException("format of month can not match with value"); } else { result = result + temp + monthValue; } } break; case DateFormatterTemporalField.DAY_FIElD: if (dateFormatterTemporalField.getCount() == 2) { int dayValue = jalaliDate.getDay(); if (dayValue < 10) { temp = "0"; } result = result + temp + dayValue; } else // count equals to one { int dayValue = jalaliDate.getDay(); if (dayValue < 10) { throw new IllegalArgumentException("format of day can not match with value"); } else { result = result + temp + dayValue; } } break; case DateFormatterTemporalField.SPACE_FIElD: for (int i = 0; i < dateFormatterTemporalField.getCount(); i++) result = result + " "; break; case DateFormatterTemporalField.DASH_FIElD: for (int i = 0; i < dateFormatterTemporalField.getCount(); i++) result = result + "-"; break; case DateFormatterTemporalField.SLASH_FIElD: for (int i = 0; i < dateFormatterTemporalField.getCount(); i++) result = result + "/"; break; case DateFormatterTemporalField.MONTH_STRING_FIElD: String monthString = formatLanguage == FORMAT_IN_PERSIAN ? jalaliDate.getMonthPersian().getStringInPersian() : jalaliDate.getMonthPersian().getStringInEnglish(); result = result + monthString; break; } return result; } /** * Replace english numbers with persian ones. *

* It changes each english number with its persian version, * for example 1 becomes ۱. * * @param resultChar an english number that will be changed to persian. * @return the persian version of number */ private char replaceWithPersian(char resultChar) { if (resultChar == '0') return '\u0660'; if (resultChar == '1') return '\u0661'; if (resultChar == '2') return '\u0662'; if (resultChar == '3') return '\u0663'; if (resultChar == '4') return '\u0664'; if (resultChar == '5') return '\u0665'; if (resultChar == '6') return '\u0666'; if (resultChar == '7') return '\u0667'; if (resultChar == '8') return '\u0668'; if (resultChar == '9') return '\u0669'; return resultChar; } // validate entered pattern and then inflate the array list of place holders ( temporal fields ) private void parsePattern(String pattern) { for (int pos = 0; pos < pattern.length(); pos++) { char cur = pattern.charAt(pos); if ((cur >= 'A' && cur <= 'Z') || (cur >= 'a' && cur <= 'z') || (cur == ' ') || (cur == '/') || (cur == '-')) { int start = pos++; for (; pos < pattern.length() && pattern.charAt(pos) == cur; pos++) ; // short loop int count = pos - start; if (isValidPatternCharacter(String.valueOf(cur))) { parseField(cur, count); // create each temporal field } pos--; } else { throw new IllegalArgumentException("Invalid character for formatting: " + cur); } } } // an array list of place holders for each pattern element, each pattern element will be mapped to one temporal field private ArrayList dateFormatterTemporalFields = new ArrayList<>(); /* according to position and numbers of each pattern element ( like mm ), it creates one temporal field and add it to list of temporal fields. */ private void parseField(char cur, int count) { switch (cur) { case 'y': if (count == 2) { throw new IllegalArgumentException("Not enough pattern letters: " + cur); } if (count == 2) { dateFormatterTemporalFields.add(new DateFormatterTemporalField(2, DateFormatterTemporalField.YEAR_FIElD)); } else if (count == 4) { dateFormatterTemporalFields.add(new DateFormatterTemporalField(4, DateFormatterTemporalField.YEAR_FIElD)); } else { throw new IllegalArgumentException("Too many pattern letters: " + cur); } break; case 'm': if (count == 1) { dateFormatterTemporalFields.add(new DateFormatterTemporalField(1, DateFormatterTemporalField.MONTH_FIElD)); } else if (count == 2) { dateFormatterTemporalFields.add(new DateFormatterTemporalField(2, DateFormatterTemporalField.MONTH_FIElD)); } else { throw new IllegalArgumentException("Too many pattern letters: " + cur); } break; case 'M': if (count == 1) { dateFormatterTemporalFields.add(new DateFormatterTemporalField(1, DateFormatterTemporalField.MONTH_STRING_FIElD)); } else { throw new IllegalArgumentException("Too many pattern letters: " + cur); } break; case 'd': if (count == 1) { dateFormatterTemporalFields.add(new DateFormatterTemporalField(1, DateFormatterTemporalField.DAY_FIElD)); } else if (count == 2) { dateFormatterTemporalFields.add(new DateFormatterTemporalField(2, DateFormatterTemporalField.DAY_FIElD)); } else { throw new IllegalArgumentException("Too many pattern letters: " + cur); } break; case ' ': dateFormatterTemporalFields.add(new DateFormatterTemporalField(count, DateFormatterTemporalField.SPACE_FIElD)); break; case '-': dateFormatterTemporalFields.add(new DateFormatterTemporalField(count, DateFormatterTemporalField.DASH_FIElD)); break; case '/': dateFormatterTemporalFields.add(new DateFormatterTemporalField(count, DateFormatterTemporalField.SLASH_FIElD)); break; } } /** * Valid pattern characters that can be used for formatting jalali date *

* y: year (Note: use yyyy) * m: month in number (Note: use mm) * M: month in word (Note: use M) * d: day (Note: use dd) * ' ', '/' and '-' can be used as a separator. */ private String[] validPatternCharacters = {"y", "m", "M", "d", " ", "/", "-"}; private boolean isValidPatternCharacter(String character) { // for (String validPatternCharacter : validPatternCharacters) // { // if (validPatternCharacter.equals(character)) // { // return true; // } // } // return false; return Arrays.stream(validPatternCharacters).anyMatch(x -> x.equals(character)); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy