001    /**
002     * 
003     * $Revision: 1.8 $ $Date: 2008/05/28 13:43:31 $
004     *
005     * This file is part of ***  M y C o R e  ***
006     * See http://www.mycore.de/ for details.
007     *
008     * This program is free software; you can use it, redistribute it
009     * and / or modify it under the terms of the GNU General Public License
010     * (GPL) as published by the Free Software Foundation; either version 2
011     * of the License or (at your option) any later version.
012     *
013     * This program is distributed in the hope that it will be useful, but
014     * WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program, in a file called gpl.txt or license.txt.
020     * If not, write to the Free Software Foundation Inc.,
021     * 59 Temple Place - Suite 330, Boston, MA  02111-1307 USA
022     */
023    
024    package org.mycore.common;
025    
026    import java.util.Locale;
027    
028    import com.ibm.icu.text.SimpleDateFormat;
029    import com.ibm.icu.util.BuddhistCalendar;
030    import com.ibm.icu.util.Calendar;
031    import com.ibm.icu.util.CopticCalendar;
032    import com.ibm.icu.util.EthiopicCalendar;
033    import com.ibm.icu.util.GregorianCalendar;
034    import com.ibm.icu.util.HebrewCalendar;
035    import com.ibm.icu.util.IslamicCalendar;
036    import com.ibm.icu.util.JapaneseCalendar;
037    
038    import org.apache.log4j.Logger;
039    import org.mycore.common.MCRException;
040    
041    /**
042     * This class implements all methods for handling calendars in MyCoRe objects
043     * and data models. It use the GPL licensed ICU library of IBM.
044     * 
045     * @author Jens Kupferschmidt
046     * @author Thomas Junge
047     * @version $Revision: 1.8 $ $Date: 2008/05/28 13:43:31 $
048     * @see <a href="http://icu.sourceforge.net/">http://icu.sourceforge.net/</a>
049     */
050    public class MCRCalendar {
051    
052        /** Logger */
053        static Logger LOGGER = Logger.getLogger(MCRCalendar.class.getName());
054    
055        /** Tag for calendars */
056        public static String TAG_BUDDHIST = "buddhist";
057    
058        public static String TAG_CHINESE = "chinese";
059    
060        public static String TAG_COPTIC = "coptic";
061    
062        public static String TAG_ETHIOPIC = "ethiopic";
063    
064        public static String TAG_GREGORIAN = "gregorian";
065    
066        public static String TAG_HEBREW = "hebrew";
067    
068        public static String TAG_ISLAMIC = "islamic";
069    
070        public static String TAG_ISLAMIC_CIVIL = "islamic-civil";
071    
072        public static String TAG_JAPANESE = "japanese";
073    
074        public static String TAG_JULIAN = "julian";
075    
076        public static String TAG_PERSIC = "persic";
077    
078        public static String TAG_ARMENIAN = "armenian";
079    
080        public static String TAG_EGYPTIAN = "egyptian";
081    
082        /** Minimum Julian Day number is 0 = 01.01.4713 BC */
083        public static int MIN_JULIAN_DAY_NUMBER = 0;
084    
085        /** Maximum Julian Day number is 3182057 = 31.12.3999 */
086        public static int MAX_JULIAN_DAY_NUMBER = 3182057;
087    
088        /** all available calendars of ICU */
089        public static String CALENDARS_ICU[] = { TAG_BUDDHIST, TAG_CHINESE, TAG_COPTIC, TAG_ETHIOPIC, TAG_GREGORIAN, TAG_HEBREW, TAG_ISLAMIC, TAG_ISLAMIC_CIVIL, TAG_JAPANESE };
090    
091        /** convert following calendars from input to gregorian */
092        public static String CALENDARS_INPUT[] = { TAG_GREGORIAN, TAG_JULIAN, TAG_ISLAMIC, TAG_BUDDHIST, TAG_COPTIC, TAG_ETHIOPIC, TAG_PERSIC, TAG_JAPANESE, TAG_ARMENIAN, TAG_EGYPTIAN };
093    
094        /**
095         * This method convert a ancient date to a GregorianCalendar value. For
096         * syntax of the string see javadocs of calendar methods.
097         * 
098         * @param datestr
099         *            the date as string.
100         * @param last
101         *            the value is true if the date should be filled with the
102         *            highest value of month or day like 12 or 31 else it fill the
103         *            date with the lowest value 1 for month and day.
104         * 
105         * @return the GregorianCalendar date value or null if an error was
106         *         occurred.
107         * @exception a
108         *                MCRException if parsing has an error
109         */
110        public static final GregorianCalendar getGregorianHistoryDate(String datestr, boolean last) throws MCRException {
111            return getGregorianHistoryDate(datestr, last, TAG_GREGORIAN);
112        }
113    
114        /**
115         * This method convert a ancient date to a GregorianCalendar value. For
116         * syntax of the string see javadocs of calendar methods.
117         * 
118         * @param datestr
119         *            the date as string.
120         * @param last
121         *            the value is true if the date should be filled with the
122         *            highest value of month or day like 12 or 31 else it fill the
123         *            date with the lowest value 1 for month and day.
124         * @param calstr
125         *            the calendar as String, kind of the calendar name
126         *            ('gregorian', 'julian', 'islamic', 'coptic', 'ethiopic',
127         *            'buddhist', 'japanese', 'persic', 'armenian', 'egyptian')
128         * 
129         * @return the GregorianCalendar date value or null if an error was
130         *         occurred.
131         * @exception a
132         *                MCRException if parsing has an error
133         */
134        public static final GregorianCalendar getGregorianHistoryDate(String datestr, boolean last, String calstr) throws MCRException {
135            // check input
136            String calstrtmp = checkCalendarName(calstr);
137            Calendar cal = checkHistoryDate(datestr, last, calstrtmp);
138            
139            
140            GregorianCalendar gcal = new GregorianCalendar();
141            int year = 0;
142            int mon = 0;
143            int day = 0;
144            int area = 0;
145    
146            try {
147                if (cal instanceof GregorianCalendar && (calstrtmp.equals(TAG_GREGORIAN) || calstrtmp.equals(TAG_JULIAN) || calstrtmp.equals(TAG_PERSIC) || calstrtmp.equals(TAG_ARMENIAN) || calstrtmp.equals(TAG_EGYPTIAN))) {
148                    gcal = (GregorianCalendar) cal;
149                } else if (cal instanceof IslamicCalendar) {
150                    gcal.setTime(cal.getTime());
151    
152                    year = gcal.get(Calendar.YEAR);
153                    mon = gcal.get(Calendar.MONTH) + 1;
154                    day = gcal.get(Calendar.DATE);
155                    area = gcal.get(Calendar.ERA);
156    
157                    if ((10000 * year + 100 * mon + day) <= (15821004)) {
158                        // Change Julian to Gregorian
159                        int TD = 0;
160                        int jh;
161                        if (year % 100 == 0 && mon <= 2)
162                            jh = (year - 1) / 100;
163                        else
164                            jh = year / 100;
165                        int a = jh / 4;
166                        int b = jh % 4;
167                        TD = 3 * a + b - 2;
168                        if (area == 1) { // AD
169                            if (year == 1582 && mon == 9 && day > 24) {
170                                gcal.set(year, mon - 1, day + TD + 35 - day);
171                                TD = 0;
172                            }
173                            if (year == 1582 && mon == 10 && day < 5) {
174                                gcal.set(year, mon - 1, day + TD + 5 - day);
175                                TD = 0;
176                            }
177                            if (year == 1582 && mon == 10 && day >= 5 && day < 15) {
178                                gcal.set(year, mon - 1, day + TD);
179                                TD = 0;
180                            }
181                        } else
182                            TD = -TD - 4; // BC
183                        gcal.add(Calendar.DATE, TD);
184                    }
185                } else if (cal instanceof CopticCalendar && calstrtmp.equals(TAG_COPTIC)) {
186                    gcal.setTime(cal.getTime());
187                    year = gcal.get(Calendar.YEAR);
188                    mon = gcal.get(Calendar.MONTH) + 1;
189                    day = gcal.get(Calendar.DATE);
190                    area = gcal.get(Calendar.ERA);
191                    if ((10000 * year + 100 * mon + day) <= (15821004)) {
192                        // Change julian to gregorian
193                        int TD = 0;
194                        int jh;
195                        if (year % 100 == 0 && mon <= 2)
196                            jh = (year - 1) / 100;
197                        else
198                            jh = year / 100;
199                        int a = jh / 4;
200                        int b = jh % 4;
201                        TD = 3 * a + b - 2;
202                        if (area == 1) { // AD
203                            if (year == 1582 && mon == 9 && day > 24) {
204                                gcal.set(year, mon - 1, day + TD + 35 - day);
205                                TD = 0;
206                            }
207                            if (year == 1582 && mon == 10 && day < 5) {
208                                gcal.set(year, mon - 1, day + TD + 5 - day);
209                                TD = 0;
210                            }
211                            if (year == 1582 && mon == 10 && day >= 5 && day < 15) {
212                                gcal.set(year, mon - 1, day + TD);
213                                TD = 0;
214                            }
215                        } else
216                            TD = -TD - 4; // BC
217                        gcal.add(Calendar.DATE, TD);
218                    }
219                } else if (cal instanceof EthiopicCalendar && calstrtmp.equals(TAG_ETHIOPIC)) {
220                    gcal.setTime(cal.getTime());
221                    year = gcal.get(Calendar.YEAR);
222                    mon = gcal.get(Calendar.MONTH) + 1;
223                    day = gcal.get(Calendar.DATE);
224                    area = gcal.get(Calendar.ERA);
225                    if ((10000 * year + 100 * mon + day) <= (15821004)) {
226                        // Change julian to gregorian
227                        int TD = 0;
228                        int jh;
229                        if (year % 100 == 0 && mon <= 2)
230                            jh = (year - 1) / 100;
231                        else
232                            jh = year / 100;
233                        int a = jh / 4;
234                        int b = jh % 4;
235                        TD = 3 * a + b - 2;
236                        if (area == 1) { // AD
237                            if (year == 1582 && mon == 9 && day > 24) {
238                                gcal.set(year, mon - 1, day + TD + 35 - day);
239                                TD = 0;
240                            }
241                            if (year == 1582 && mon == 10 && day < 5) {
242                                gcal.set(year, mon - 1, day + TD + 5 - day);
243                                TD = 0;
244                            }
245                            if (year == 1582 && mon == 10 && day >= 5 && day < 15) {
246                                gcal.set(year, mon - 1, day + TD);
247                                TD = 0;
248                            }
249                        } else
250                            TD = -TD - 4; // BC
251                        gcal.add(Calendar.DATE, TD);
252                    }
253                } else if (cal instanceof BuddhistCalendar && calstrtmp.equals(TAG_BUDDHIST)) {
254                    gcal.setTime(cal.getTime());
255                    gcal.add(Calendar.DATE, 0);
256                } else if (cal instanceof GregorianCalendar && calstrtmp.equals(TAG_JAPANESE)) {
257                    gcal.setTime(cal.getTime());
258                    gcal.add(Calendar.DATE, 0);
259                } else if (cal instanceof HebrewCalendar && calstrtmp.equals(TAG_HEBREW)) {
260                    gcal.setTime(cal.getTime());
261                    year = gcal.get(Calendar.YEAR);
262                    mon = gcal.get(Calendar.MONTH) + 1;
263                    day = gcal.get(Calendar.DATE);
264                    if ((10000 * year + 100 * mon + day) <= (15821004)) {
265                        // 
266                        int TD = 0;
267                        int jh;
268                        if (year % 100 == 0 && mon <= 2)
269                            jh = (year - 1) / 100;
270                        else
271                            jh = year / 100;
272                        int a = jh / 4;
273                        int b = jh % 4;
274                        TD = 3 * a + b - 2;
275                        if (year == 1582 && mon == 9 && day > 24) {
276                            gcal.set(year, mon - 1, day + TD + 35 - day);
277                            TD = 0;
278                        }
279                        if (year == 1582 && mon == 10 && day < 5) {
280                            gcal.set(year, mon - 1, day + TD + 5 - day);
281                            TD = 0;
282                        }
283                        if (year == 1582 && mon == 10 && day >= 5 && day < 15) {
284                            gcal.set(year, mon - 1, day + TD);
285                            TD = 0;
286                        }
287                        gcal.add(Calendar.DATE, TD);
288                    }
289                }
290    
291            } catch (MCRException ex) {
292            }
293            return gcal;
294        }
295    
296        /**
297         * This method test a ancient date string. For syntax of the string see
298         * javadocs of calendar methods.
299         * 
300         * @param datestr
301         *            the date as string.
302         * @param last
303         *            the value is true if the date should be filled with the
304         *            highest value of month or day like 12 or 31 else it fill the
305         *            date with the lowest value 1 for month and day.
306         * @param calstr
307         *            the calendar as String, kind of the calendar ('gregorian',
308         *            'julian', 'islamic', 'coptic', 'ethiopic', 'buddhist',
309         *            'japanese', 'persic', ''armenian, 'egyptian')
310         * 
311         * @return the GregorianCalendar date value or null if an error was
312         *         occurred.
313         */
314        public static final boolean testHistoryDate(String datestr, boolean last, String calstr) {
315            try {
316                Calendar cal = checkHistoryDate(datestr, last, calstr);
317                if (cal == null)
318                    return false;
319                return true;
320            } catch (MCRException ex) {
321                return false;
322            }
323        }
324    
325        /**
326         * This method check the String of the calendar name.
327         * 
328         * @param calstr
329         *            the calendar name as String, kind of the calendars are
330         *            ('gregorian', 'julian', 'islamic', 'buddhist', 'coptic',
331         *            'ethiopic', 'persic', 'japanese', 'armenian' or 'egyptian' )
332         * @return the calendar string or gregorian if an error was occurred
333         * @exception a
334         *                MCRException if parsing has an error
335         */
336        private static final String checkCalendarName(String calstr) {
337            if ((calstr == null) || (calstr.trim().length() == 0)) {
338                throw new MCRException("The calendar name is null or empty.");
339            }
340            for (int i = 0; i < CALENDARS_INPUT.length; i++) {
341                if (CALENDARS_INPUT[i].equals(calstr)) {
342                    return calstr;
343                }
344            }
345            throw new MCRException("Can't find the calendar name " + calstr + ".");
346        }
347    
348        /**
349         * This method check a ancient date string for the given calendar. For
350         * syntax of the string see javadocs of calendar methods.
351         * 
352         * @param datestr
353         *            the date as string.
354         * @param last
355         *            the value is true if the date should be filled with the
356         *            highest value of month or day like 12 or 31 else it fill the
357         *            date with the lowest value 1 for month and day.
358         * @param calstr
359         *            the calendar name as String, kind of the calendars are
360         *            ('gregorian', 'julian', 'islamic', 'buddhist', 'coptic',
361         *            'ethiopic', 'persic', 'japanese', 'armenian' or 'egyptian' )
362         * 
363         * @return the ICU Calendar date value or null if an error was occurred.
364         * @exception a
365         *                MCRException if parsing has an error
366         */
367        private static final Calendar checkHistoryDate(String datestr, boolean last, String calstr) throws MCRException {
368            Calendar out = null;
369            // check datestr String
370            LOGGER.debug("Input checkHistoryDate " + datestr + "  " + calstr + "  " + Boolean.toString(last));
371            if ((datestr == null) || (datestr.trim().length() == 0)) {
372                throw new MCRException("The ancient date string is null or empty");
373            }
374            // Check calendar string
375            String caltmp = checkCalendarName(calstr);
376            // select for calendar
377            if (caltmp.equals(TAG_GREGORIAN)) {
378                return getCalendarFromGregorianDate(datestr, last);
379            }
380            if (caltmp.equals(TAG_JULIAN)) {
381                return getCalendarFromJulianDate(datestr, last);
382            }
383            if (caltmp.equals(TAG_ISLAMIC)) {
384                return getCalendarFromIslamicDate(datestr, last);
385            }
386            if (caltmp.equals(TAG_COPTIC)) {
387                return getCalendarFromCopticDate(datestr, last);
388            }
389            if (caltmp.equals(TAG_ETHIOPIC)) {
390                return getCalendarFromEthiopicDate(datestr, last);
391            }
392            if (caltmp.equals(TAG_BUDDHIST)) {
393                return getCalendarFromBuddhistDate(datestr, last);
394            }
395            if (caltmp.equals(TAG_PERSIC)) {
396                return getCalendarFromPersicDate(datestr, last);
397            }
398            if (caltmp.equals(TAG_ARMENIAN)) {
399                return getCalendarFromArmenianDate(datestr, last);
400            }
401            if (caltmp.equals(TAG_EGYPTIAN)) {
402                return getCalendarFromEgyptianDate(datestr, last);
403            }
404            if (caltmp.equals(TAG_JAPANESE)) {
405                return getCalendarFromJapaneseDate(datestr, last);
406            }
407            if (caltmp.equals(TAG_HEBREW)) {
408                return getCalendarFromHebrewDate(datestr, last);
409            }
410            return out;
411        }
412    
413        /**
414         * This method convert a ancient date to a GregorianCalendar value. The
415         * syntax for the gregorian input is: <br />
416         * <ul>
417         * <li> [[[t]t.][m]m.][yyy]y [v. Chr.]</li>
418         * <li> [[[t]t.][m]m.][yyy]y [AD|BC]</li>
419         * <li> [-|AD|BC] [[[t]t.][m]m.][yyy]y</li>
420         * <li> y[yyy][-m[m][-t[t]]] [v. Chr.]</li>
421         * <li> y[yyy][-m[m][-t[t]]] [AD|BC]</li>
422         * <li> [-|AD|BC] y[yyy][-m[m][-t[t]]]</li>
423         * </ul>
424         * 
425         * @param indatestr
426         *            the date as string.
427         * @param last
428         *            the value is true if the date should be filled with the
429         *            highest value of month or day like 12 or 31 else it fill the
430         *            date with the lowest value 1 for month and day.
431         * 
432         * @return the GregorianCalendar date value or null if an error was
433         *         occurred.
434         * @exception a
435         *                MCRException if parsing has an error
436         */
437        private static final GregorianCalendar getCalendarFromGregorianDate(String datestr, boolean last) throws MCRException {
438            try {
439                // look for BC
440                datestr = datestr.toUpperCase();
441                boolean bc = false;
442                int start = 0;
443                int ende = datestr.length();
444                if (datestr.substring(0, 1).equals("-")) {
445                    bc = true;
446                    start = 1;
447                } else {
448                    if (datestr.length() > 2) {
449                        int i = datestr.indexOf("AD");
450                        if (i != -1) {
451                            if (i == 0) {
452                                bc = false;
453                                start = 2;
454                            } else {
455                                bc = false;
456                                start = 0;
457                                ende = i - 1;
458                            }
459                        }
460                        i = datestr.indexOf("BC");
461                        if (i != -1) {
462                            if (i == 0) {
463                                bc = true;
464                                start = 2;
465                            } else {
466                                bc = true;
467                                start = 0;
468                                ende = i - 1;
469                            }
470                        }
471                    }
472                    if (datestr.length() > 7) {
473                        int i = datestr.indexOf("N. CHR");
474                        if (i != -1) {
475                            if (i == 0) {
476                                bc = false;
477                                start = 7;
478                            } else {
479                                bc = false;
480                                start = 0;
481                                ende = i - 1;
482                            }
483                        }
484                        i = datestr.indexOf("V. CHR");
485                        if (i != -1) {
486                            if (i == 0) {
487                                bc = true;
488                                start = 7;
489                            } else {
490                                bc = true;
491                                start = 0;
492                                ende = i - 1;
493                            }
494                        }
495                    }
496                }
497                datestr = datestr.substring(start, ende).trim();
498                
499               // german or ISO?
500                start = 0;
501                boolean iso = false;
502                String token = ".";
503                if (datestr.indexOf("-", start + 1) != -1) {
504                    iso = true;
505                    token = "-";
506                }
507                // only a year?
508                int firstdot = datestr.indexOf(token, start + 1);
509                int secdot = -1;
510                if (firstdot != -1) {
511                    secdot = datestr.indexOf(token, firstdot + 1);
512                }
513                int day = 0;
514                int mon = 0;
515                int year = 0;
516                if (secdot != -1) {
517                    if (iso) {
518                        year = Integer.parseInt(datestr.substring(start, firstdot));
519                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
520                        day = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
521                    } else {
522                        day = Integer.parseInt(datestr.substring(start, firstdot));
523                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
524                        year = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
525                    }
526    
527                    if (year == 1582 && mon == 9 && day >= 5 && day < 15) {
528                        day = 15;
529                    } // the problem on the year 1582
530                } else {
531                    if (firstdot != -1) {
532                        if (iso) {
533                            year = Integer.parseInt(datestr.substring(start, firstdot));
534                            mon = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length())) - 1;
535                        } else {
536                            mon = Integer.parseInt(datestr.substring(start, firstdot)) - 1;
537                            year = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length()));
538                        }
539                        if (last) {
540                            if (mon == 0 || mon == 2 || mon == 4 || mon == 6 || mon == 7 || mon == 9 || mon == 11) {
541                                day = 31;
542                            }
543                            if (mon == 1) {
544                                day = 28;
545                            }
546    
547                            if (mon == 3 || mon == 5 || mon == 8 || mon == 10) {
548                                day = 30;
549                            }
550    
551                        } else {
552                            day = 1;
553                        }
554                    } else {
555                        year = Integer.parseInt(datestr.substring(start, datestr.length()));
556                        if (last) {
557                            mon = 11;
558                            day = 31;
559                        } else {
560                            mon = 0;
561                            day = 1;
562                        }
563                    }
564                }
565                GregorianCalendar newdate = new GregorianCalendar();
566                // test of the monthly
567                if (mon > 11 || mon < 0) {
568    
569                    throw new MCRException("The month of the date is inadmissible.");
570                }
571    
572                // Test of the daily
573                if (((mon == 0 || mon == 2 || mon == 4 || mon == 6 || mon == 7 || mon == 9 || mon == 11) && day > 31) || ((mon == 3 || mon == 5 || mon == 8 || mon == 10) && day > 30) || (mon == 1 && day > 29 && year % 4 == 0) || (mon == 1 && day > 28 && year % 4 > 0) || day < 1) {
574                    throw new MCRException("The day of the date is inadmissible.");
575                }
576                // set AD/BC
577                newdate.set(year, mon, day);
578                if (bc) {
579                    newdate.set(GregorianCalendar.ERA, GregorianCalendar.BC);
580                } else {
581                    newdate.set(GregorianCalendar.ERA, GregorianCalendar.AD);
582                }
583                newdate.add(Calendar.DATE, 0);
584                return newdate;
585            } catch (Exception e) {
586                throw new MCRException("The ancient gregorian date is false.", e);
587            }
588        }
589    
590        /**
591         * This method convert a JulianCalendar date to a GregorianCalendar value.
592         * The syntax for the julian input is: <br />
593         * <ul>
594         * <li> [[[t]t.][m]m.][yyy]y [v.Chr.]</li>
595         * <li> [[[t]t.][m]m.][yyy]y [AD|BC]</li>
596         * <li> [-|AD|BC] [[[t]t.][m]m.][yyy]y</li>
597         * <li> y[yyy][-m[m][-t[t]]] [v.Chr.]</li>
598         * <li> y[yyy][-m[m][-t[t]]] [AD|BC]</li>
599         * <li> [-|AD|BC] y[yyy][-m[m][-t[t]]]</li>
600         * </ul>
601         * 
602         * @param datestr
603         *            the date as string.
604         * @param last
605         *            the value is true if the date should be filled with the
606         *            highest value of month or day like 12 or 31 else it fill the
607         *            date with the lowest value 1 for month and day.
608         * 
609         * @return the GregorianCalendar date value or null if an error was
610         *         occurred.
611         * @exception a
612         *                MCRException if parsing has an error
613         */
614        private static final GregorianCalendar getCalendarFromJulianDate(String datestr, boolean last) throws MCRException {
615            try {
616                // look for v. Chr.
617                datestr = datestr.toUpperCase();
618                boolean bc = false;
619                int start = 0;
620                int ende = datestr.length();
621                if (datestr.substring(0, 1).equals("-")) {
622                    bc = true;
623                    start = 1;
624                } else {
625                    if (datestr.length() > 2) {
626                        int i = datestr.indexOf("AD");
627                        if (i != -1) {
628                            if (i == 0) {
629                                bc = false;
630                                start = 2;
631                            } else {
632                                bc = false;
633                                start = 0;
634                                ende = i - 1;
635                            }
636                        }
637                        i = datestr.indexOf("BC");
638                        if (i != -1) {
639                            if (i == 0) {
640                                bc = true;
641                                start = 2;
642                            } else {
643                                bc = true;
644                                start = 0;
645                                ende = i - 1;
646                            }
647                        }
648                    }
649                    if (datestr.length() > 7) {
650                        int i = datestr.indexOf("N. CHR");
651                        if (i != -1) {
652                            if (i == 0) {
653                                bc = false;
654                                start = 7;
655                            } else {
656                                bc = false;
657                                start = 0;
658                                ende = i - 1;
659                            }
660                        }
661                        i = datestr.indexOf("V. CHR");
662                        if (i != -1) {
663                            if (i == 0) {
664                                bc = true;
665                                start = 7;
666                            } else {
667                                bc = true;
668                                start = 0;
669                                ende = i - 1;
670                            }
671                        }
672                    }
673                }
674                datestr = datestr.substring(start, ende).trim();
675    
676                // german or ISO?
677                start = 0;
678                boolean iso = false;
679                String token = ".";
680    
681                if (datestr.indexOf("-", start + 1) != -1) {
682                    iso = true;
683                    token = "-";
684                }
685    
686                // only a year
687                int firstdot = datestr.indexOf(token, start + 1);
688                int secdot = -1;
689                if (firstdot != -1) {
690                    secdot = datestr.indexOf(token, firstdot + 1);
691                }
692    
693                int day = 0;
694                int mon = 0;
695                int year = 0;
696                int TD = 0; // day for correction
697                if (secdot != -1) {
698                    try {
699                        if (iso) {
700                            year = Integer.parseInt(datestr.substring(start, firstdot));
701                            mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
702                            day = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
703                        } else {
704                            day = Integer.parseInt(datestr.substring(start, firstdot));
705                            mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
706                            year = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
707                        }
708                        // Change Julian to Gregorian
709                        int jh;
710                        if (year % 100 == 0 && mon <= 2)
711                            jh = (year - 1) / 100;
712                        else
713                            jh = year / 100;
714                        int a = jh / 4;
715                        int b = jh % 4;
716                        TD = 3 * a + b - 2;
717                        if (year == 1582 && mon == 8 && day > 24) {
718                            mon = 9;
719                            day = day + TD + 5 - day;
720                            TD = 0;
721                        }
722                        if (year == 1582 && mon == 9 && day < 5) {
723                            day = day + TD + 5 - day;
724                            TD = 0;
725                        }
726                        if (year == 1582 && mon == 9 && day >= 5 && day < 15) {
727                            day = day + TD;
728                            TD = 0;
729                        }
730                    } catch (Exception ex) {
731                    }
732                } else {
733                    if (firstdot != -1) {
734                        if (iso) {
735                            year = Integer.parseInt(datestr.substring(start, firstdot));
736                            mon = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length())) - 1;
737                        } else {
738                            mon = Integer.parseInt(datestr.substring(start, firstdot)) - 1;
739                            year = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length()));
740                        }
741    
742                        if (last) {
743                            if (mon == 0 || mon == 2 || mon == 4 || mon == 6 || mon == 7 || mon == 9 || mon == 11) {
744                                day = 31;
745                            }
746    
747                            if (mon == 1) {
748                                day = 28;
749                            }
750    
751                            if (mon == 3 || mon == 5 || mon == 8 || mon == 10) {
752                                day = 30;
753                            }
754    
755                        } else {
756                            day = 1;
757                        }
758    
759                    } else {
760                        year = Integer.parseInt(datestr.substring(start, datestr.length()));
761    
762                        if (last) {
763                            mon = 11;
764                            day = 31;
765                        } else {
766                            mon = 0;
767                            day = 1;
768                        }
769                    }
770                }
771                // test of the monthly
772                if (mon > 11 || mon < 0) {
773                    throw new MCRException("The month of the date is inadmissible.");
774                }
775    
776                // Test of the daily
777                if (((mon == 0 || mon == 2 || mon == 4 || mon == 6 || mon == 7 || mon == 9 || mon == 11) && day > 31) || ((mon == 3 || mon == 5 || mon == 8 || mon == 10) && day > 30) || (mon == 1 && day > 29 && year % 4 == 0) || (mon == 1 && day > 28 && year % 4 > 0) || day < 1) {
778                    throw new MCRException("The day of the date is inadmissible.");
779                }
780                // set AD/BC
781                GregorianCalendar newdate = new GregorianCalendar();
782                newdate.set(year, mon, day);
783                if (bc == true) {
784                    newdate.set(GregorianCalendar.ERA, GregorianCalendar.BC);
785                    TD = -TD - 4; // Calendar correction reversible
786                } else {
787                    newdate.set(GregorianCalendar.ERA, GregorianCalendar.AD);
788    
789                }
790    
791                newdate.add(Calendar.DATE, TD); // Calendar correction
792                return (GregorianCalendar) newdate;
793            } catch (Exception e) {
794                throw new MCRException("The ancient julian date is false.", e);
795            }
796        }
797    
798        /**
799         * This method convert a IslamicCalendar date to a IslamicCalendar value.
800         * The syntax for the islamic input is: <br />
801         * <ul>
802         * <li> [[[t]t.][m]m.][yyy]y [v.]H.</li>
803         * <li> [[[t]t.][m]m.][yyy]y [b.]H.</li>
804         * <li> [-] [[[t]t.][m]m.][yyy]y</li>
805         * <li> [.\u0647 | .\u0647 .\u0642] [[[t]t.][m]m.][yyy]y</li>
806         * <li> y[yyy][-m[m][-t[t]]] [v.]H.</li>
807         * <li> y[yyy][-m[m][-t[t]]] [b.]H.</li>
808         * <li> [-] y[yyy][-m[m][-t[t]]]</li>
809         * </ul>
810         * 
811         * @param datestr
812         *            the date as string.
813         * @param last
814         *            the value is true if the date should be filled with the
815         *            highest value of month or day like 12 or 30 else it fill the
816         *            date with the lowest value 1 for month and day.
817         * 
818         * @return the IslamicCalendar date value or null if an error was occurred.
819         * @exception a
820         *                MCRException if parsing has an error
821         */
822        private static final IslamicCalendar getCalendarFromIslamicDate(String datestr, boolean last) {
823            try {
824                // test before Hidschra
825                boolean bh = false;
826                int start = 0;
827                int ende = datestr.length();
828                if (datestr.substring(0, 1).equals("-")) {
829                    bh = true;
830                    start = 1;
831                } else {
832                    if (datestr.length() > 4) {
833                        int i = datestr.indexOf("v.H.");
834                        if (i != -1) {
835                            bh = true;
836                            start = 0;
837                            ende = i - 1;
838                        }
839                        i = datestr.indexOf("b.H.");
840                        if (i != -1) {
841                            bh = true;
842                            start = 0;
843                            ende = i - 1;
844                        }
845                        if (!bh) {
846                            i = datestr.indexOf("H.");
847                            if (i != -1) {
848                                bh = false;
849                                start = 0;
850                                ende = i;
851                            }
852                            if (datestr.length() > 10) {
853    
854                                i = datestr.indexOf(".\u0647.\u0642");
855                                if (i != -1) {
856                                    if (i == 0) {
857                                        bh = true;
858                                        start = 4;
859                                    }
860                                }
861                            }
862                            if (!bh) {
863                                i = datestr.indexOf(".\u0647");
864                                if (i != -1) {
865                                    if (i == 0) {
866                                        bh = false;
867                                        start = 2;
868                                    }
869                                }
870                            }
871                        }
872                    }
873                }
874    
875                datestr = datestr.substring(start, ende).trim();
876    
877                // german or ISO?
878                start = 0;
879                boolean iso = false;
880                String token = ".";
881    
882                if (datestr.indexOf("-", start + 1) != -1) {
883                    iso = true;
884                    token = "-";
885                }
886                // 
887                int firstdot = datestr.indexOf(token, start + 1);
888                int secdot = -1;
889    
890                if (firstdot != -1) {
891                    secdot = datestr.indexOf(token, firstdot + 1);
892                }
893    
894                int day = 0;
895                int mon = 0;
896                int year = 0;
897                if (secdot != -1) { // day month year
898                    if (iso) {
899                        year = Integer.parseInt(datestr.substring(start, firstdot));
900                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
901                        day = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
902                    } else {
903                        day = Integer.parseInt(datestr.substring(start, firstdot));
904                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
905                        year = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
906                    }
907                } else {
908                    if (firstdot != -1) { // month year
909                        if (iso) {
910                            year = Integer.parseInt(datestr.substring(start, firstdot));
911                            mon = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length())) - 1;
912                        } else {
913                            mon = Integer.parseInt(datestr.substring(start, firstdot)) - 1;
914                            year = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length()));
915                        }
916    
917                        if (last) {
918                            if (mon % 2 == 0)
919                                day = 30;
920                            if (mon % 2 == 1)
921                                day = 29;
922    
923                        } else {
924                            day = 1;
925                        }
926                    } else { // year
927                        year = Integer.parseInt(datestr.substring(start, datestr.length()));
928    
929                        if (last) {
930                            mon = 11;
931                            day = 29;
932                        } else {
933                            mon = 0;
934                            day = 1;
935                        }
936                    }
937                }
938                // test of the monthly
939                if (mon > 11 || mon < 0)
940                    throw new MCRException("The month of the date is inadmissible.");
941                // Test of the daily
942                if (day > 30 || (mon % 2 == 1 && mon < 11 && day > 29) || (day < 1))
943                    throw new MCRException("The day of the date is inadmissible.");
944                if (bh)
945                    year = -year + 1; // if before Hidschra
946                IslamicCalendar ical = new IslamicCalendar();
947                ical.set(year, mon, day);
948                ical.add(Calendar.DATE, 0); // Calendar correction
949    
950                return ical;
951    
952            } catch (Exception e) {
953                throw new MCRException("The ancient islamic is false.", e);
954            }
955    
956        }
957    
958        /**
959         * This method convert a HebrewCalendar date to a HebrewCalendar value. The
960         * syntax for the hebrew input is [[t]t.][m]m.][yyy]y] or
961         * [[yyy]y-[[m]m]-[[t]t].
962         * 
963         * @param datestr
964         *            the date as string.
965         * @param last
966         *            the value is true if the date should be filled with the
967         *            highest value of month or day like 13 or 30 else it fill the
968         *            date with the lowest value 1 for month and day.
969         * 
970         * @return the HebewCalendar date value or null if an error was occurred.
971         * @exception a
972         *                MCRException if parsing has an error
973         */
974    
975        private static final HebrewCalendar getCalendarFromHebrewDate(String datestr, boolean last) {
976            try {
977                int start = 0;
978                datestr = datestr.trim();
979    
980                // german or ISO?
981                start = 0;
982                boolean iso = false;
983                String token = ".";
984    
985                if (datestr.indexOf("-", start + 1) != -1) {
986                    iso = true;
987                    token = "-";
988                }
989                // 
990                int firstdot = datestr.indexOf(token, start + 1);
991                int secdot = -1;
992    
993                if (firstdot != -1) {
994                    secdot = datestr.indexOf(token, firstdot + 1);
995                }
996    
997                int day = 0;
998                int mon = 0;
999                int year = 0;
1000    
1001                if (secdot != -1) {
1002                    if (iso) {
1003                        year = Integer.parseInt(datestr.substring(start, firstdot));
1004                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
1005                        day = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
1006                    } else {
1007                        day = Integer.parseInt(datestr.substring(start, firstdot));
1008                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
1009                        year = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
1010                    }
1011                } else {
1012                    if (firstdot != -1) {
1013                        if (iso) {
1014                            year = Integer.parseInt(datestr.substring(start, firstdot));
1015                            mon = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length())) - 1;
1016                        } else {
1017                            mon = Integer.parseInt(datestr.substring(start, firstdot)) - 1;
1018                            year = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length()));
1019                        }
1020    
1021                        if (last) {
1022                            if (mon == 0 || mon == 4 || mon == 7 || mon == 9 || mon == 11) {
1023                                day = 30;
1024                            } else {
1025                                day = 29;
1026                            }
1027                        } else {
1028                            day = 1;
1029                        }
1030                    } else {
1031                        year = Integer.parseInt(datestr.substring(start, datestr.length()));
1032    
1033                        if (last) {
1034                            mon = 11;
1035                            day = 29;
1036                        } else {
1037                            mon = 0;
1038                            day = 1;
1039                        }
1040                    }
1041                }
1042                HebrewCalendar hcal = new HebrewCalendar();
1043                hcal.set(year, mon, day);
1044                return hcal;
1045    
1046            } catch (Exception e) {
1047                throw new MCRException("The ancient hebrew date is false.", e);
1048            }
1049        }
1050    
1051        /**
1052         * This method convert a CopticCalendar date to a CopticCalendar value. The
1053         * syntax for the coptic input is: <br />
1054         * <ul>
1055         * <li> [[[t]t.][m]m.][yyy]y [[A.|a.]M.]</li>
1056         * <li> [[[t]t.][m]m.][yyy]y [B.M.]</li>
1057         * <li> [-] [[[t]t.][m]m.][yyy]y</li>
1058         * <li> y[yyy][-m[m][-t[t]]] [A.|a.]M.]</li>
1059         * <li> y[yyy][-m[m][-t[t]]] [B.M.]</li>
1060         * <li> [-] y[yyy][-m[m][-t[t]]]</li>
1061         * </ul>
1062         * 
1063         * @param datestr
1064         *            the date as string.
1065         * @param last
1066         *            the value is true if the date should be filled with the
1067         *            highest value of month or day like 12 or 30 else it fill the
1068         *            date with the lowest value 1 for month and day.
1069         * 
1070         * @return the CopticCalendar date value or null if an error was occurred.
1071         * @exception a
1072         *                MCRException if parsing has an error
1073         */
1074        private static final CopticCalendar getCalendarFromCopticDate(String datestr, boolean last) {
1075            try {
1076                datestr = datestr.trim();
1077                // test before Martyrium
1078                boolean bm = false;
1079                int start = 0;
1080                int ende = datestr.length();
1081                if (datestr.substring(0, 1).equals("-")) {
1082                    bm = true;
1083                    start = 1;
1084                }
1085                datestr = datestr.substring(start).trim();
1086                start = 0;
1087                ende = datestr.length();
1088                if (datestr.length() > 4) {
1089                    int i = datestr.indexOf("B.M.");
1090                    if (i != -1) {
1091                        bm = true;
1092                        start = 0;
1093                        ende = i - 1;
1094                    }
1095                    i = datestr.indexOf("A.M.");
1096                    if (i != -1) {
1097                        start = 0;
1098                        ende = i - 1;
1099                    }
1100                    i = datestr.indexOf("a.M.");
1101                    if (i != -1) {
1102                        start = 0;
1103                        ende = i - 1;
1104                    }
1105                }
1106    
1107                datestr = datestr.substring(start, ende).trim();
1108    
1109                // german or ISO?
1110                start = 0;
1111                boolean iso = false;
1112                String token = ".";
1113    
1114                if (datestr.indexOf("-", start + 1) != -1) {
1115                    iso = true;
1116                    token = "-";
1117                }
1118                // 
1119                int firstdot = datestr.indexOf(token, start + 1);
1120                int secdot = -1;
1121    
1122                if (firstdot != -1) {
1123                    secdot = datestr.indexOf(token, firstdot + 1);
1124                }
1125    
1126                int day = 0;
1127                int mon = 0;
1128                int year = 0;
1129    
1130                if (secdot != -1) { // day, mon, year
1131                    if (iso) {
1132                        year = Integer.parseInt(datestr.substring(start, firstdot));
1133                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
1134                        day = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
1135                    } else {
1136                        day = Integer.parseInt(datestr.substring(start, firstdot));
1137                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
1138                        year = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
1139                    }
1140                } else {
1141                    if (firstdot != -1) { // mon, year
1142                        if (iso) {
1143                            year = Integer.parseInt(datestr.substring(start, firstdot));
1144                            mon = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length())) - 1;
1145                        } else {
1146                            mon = Integer.parseInt(datestr.substring(start, firstdot)) - 1;
1147                            year = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length()));
1148                        }
1149    
1150                        if (last) {
1151                            if (mon <= 11) {
1152                                day = 30;
1153                            } else {
1154                                day = 5;
1155                            }
1156                        } else {
1157                            day = 1;
1158                        }
1159                    } else { // year
1160                        year = Integer.parseInt(datestr.substring(start, datestr.length()));
1161    
1162                        if (last) {
1163                            mon = 12;
1164                            day = 5;
1165                        } else {
1166                            mon = 0;
1167                            day = 1;
1168                        }
1169                    }
1170                }
1171                // test of the monthly
1172                if (mon > 12 || mon < 0)
1173                    throw new MCRException("The month of the date is inadmissible.");
1174                // Test of the daily
1175                if (day > 30 || (day < 1) || (day > 6 && mon == 12))
1176                    throw new MCRException("The day of the date is inadmissible.");
1177                if (bm)
1178                    year = -year + 1; // if before Matyrium
1179                CopticCalendar ccal = new CopticCalendar();
1180                ccal.set(year, mon, day);
1181    
1182                ccal.add(Calendar.DATE, 0); // Calendar correction
1183    
1184                return ccal;
1185    
1186            } catch (Exception e) {
1187                throw new MCRException("The ancient coptic date is false.", e);
1188            }
1189        }
1190    
1191        /**
1192         * This method convert a JapaneseCalendar date to a JapaneseCalendar value.
1193         * The syntax for the japanese input is: <br />
1194         * <ul>
1195         * <li> [[[t]t.][m]m.][H|M|S|T][yyy]y</li>
1196         * H: Heisei; M: Meiji, S: Showa, T: Taiso
1197         * <li> [H|M|S|T]y[yyy][-m[m][-t[t]]]</li>
1198         * </ul>
1199         * 
1200         * @param datestr
1201         *            the date as string.
1202         * @param last
1203         *            the value is true if the date should be filled with the
1204         *            highest value of month or day like 12 or 30 else it fill the
1205         *            date with the lowest value 1 for month and day.
1206         * 
1207         * @return the JapaneseCalendar date value or null if an error was occurred.
1208         * @exception a
1209         *                MCRException if parsing has an error
1210         */
1211        private static final JapaneseCalendar getCalendarFromJapaneseDate(String datestr, boolean last) {
1212            try {
1213                datestr = datestr.trim();
1214    
1215                // boolean bm = false;
1216                int era = 0;
1217                int start = 0;
1218                int ende = datestr.length();
1219    
1220                // german or ISO?
1221                start = 0;
1222                boolean iso = false;
1223                String token = ".";
1224    
1225                if (datestr.indexOf("-", start + 1) != -1) {
1226                    iso = true;
1227                    token = "-";
1228                }
1229                // 
1230                int firstdot = datestr.indexOf(token, start + 1);
1231                int secdot = -1;
1232    
1233                if (firstdot != -1) {
1234                    secdot = datestr.indexOf(token, firstdot + 1);
1235                }
1236    
1237                int day = 0;
1238                int mon = 0;
1239                int year = 0;
1240                String syear = "";
1241                if (secdot != -1) { // day, mon, year
1242                    if (iso) {
1243                        syear = datestr.substring(start, firstdot);
1244                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
1245                        day = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
1246                    } else {
1247                        day = Integer.parseInt(datestr.substring(start, firstdot));
1248                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
1249                        syear = datestr.substring(secdot + 1, datestr.length());
1250                    }
1251                } else {
1252                    if (firstdot != -1) { // mon, year
1253                        if (iso) {
1254                            syear = datestr.substring(start, firstdot);
1255                            mon = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length())) - 1;
1256                        } else {
1257                            mon = Integer.parseInt(datestr.substring(start, firstdot)) - 1;
1258                            syear = datestr.substring(firstdot + 1, datestr.length());
1259                        }
1260    
1261                        if (last) {
1262                            if (mon <= 11) {
1263                                day = 30;
1264                            } else {
1265                                day = 5;
1266                            }
1267                        } else {
1268                            day = 1;
1269                        }
1270                    } else { // year
1271                        syear = datestr.substring(start, datestr.length());
1272    
1273                        if (last) {
1274                            mon = 12;
1275                            day = 5;
1276                        } else {
1277                            mon = 0;
1278                            day = 1;
1279                        }
1280                    }
1281                }
1282    
1283                if (syear.substring(0, 1).equals("H"))
1284                    era = 235;
1285                else if (syear.substring(0, 1).equals("S"))
1286                    era = 234;
1287                else if (syear.substring(0, 1).equals("T"))
1288                    era = 233;
1289                else if (syear.substring(0, 1).equals("M"))
1290                    era = 232;
1291                year = Integer.parseInt(syear.substring(1).trim());
1292                // test of the monthly
1293                if (mon > 12 || mon < 0)
1294                    throw new MCRException("The month of the date is inadmissible.");
1295                // Test of the daily
1296                if (day > 30 || (day < 1) || (day > 6 && mon == 12))
1297                    throw new MCRException("The day of the date is inadmissible.");
1298    
1299                JapaneseCalendar jcal = new JapaneseCalendar();
1300                // GregorianCalendar jcal = new GregorianCalendar();
1301                jcal.set(year, mon, day);
1302                jcal.set(JapaneseCalendar.ERA, era);
1303                jcal.add(Calendar.DATE, 0); // Calendar correction
1304                GregorianCalendar xcal = new GregorianCalendar();
1305                xcal.setTime(jcal.getTime());
1306    
1307                return jcal;
1308    
1309            } catch (Exception e) {
1310                throw new MCRException("The ancient jacanese date is false.", e);
1311            }
1312        }
1313    
1314        /**
1315         * This method convert a EthiopicCalendar date to a EthiopicCalendar value.
1316         * The syntax for the ethiopic input is: <br />
1317         * <ul>
1318         * <li> [[[t]t.][m]m.][yyy]y [E.E.]</li>
1319         * <li> [-] [[[t]t.][m]m.][yyy]y</li>
1320         * <li> y[yyy][-m[m][-t[t]]] [E.E.]</li>
1321         * <li> [-] y[yyy][-m[m][-t[t]]]</li>
1322         * </ul>
1323         * 
1324         * @param datestr
1325         *            the date as string.
1326         * @param last
1327         *            the value is true if the date should be filled with the
1328         *            highest value of month or day like 13 or 30 else it fill the
1329         *            date with the lowest value 1 for month and day.
1330         * 
1331         * @return the EthiopicCalendar date value or null if an error was occurred.
1332         * @exception a
1333         *                MCRException if parsing has an error
1334         */
1335        private static final EthiopicCalendar getCalendarFromEthiopicDate(String datestr, boolean last) {
1336            try {
1337                datestr = datestr.trim();
1338                // test before Christi
1339                boolean bc = false;
1340                int start = 0;
1341                int ende = datestr.length();
1342                if (datestr.substring(0, 1).equals("-")) {
1343                    bc = true;
1344                    start = 1;
1345                }
1346                datestr = datestr.substring(start).trim();
1347                start = 0;
1348                ende = datestr.length();
1349                if (datestr.length() > 4) {
1350                    int i = datestr.indexOf("E.E.");
1351                    if (i != -1) {
1352                        start = 0;
1353                        ende = i - 1;
1354                    }
1355                    datestr = datestr.substring(start, ende).trim();
1356                }
1357    
1358                // german or ISO?
1359                start = 0;
1360                boolean iso = false;
1361                String token = ".";
1362    
1363                if (datestr.indexOf("-", start + 1) != -1) {
1364                    iso = true;
1365                    token = "-";
1366                }
1367                // 
1368                int firstdot = datestr.indexOf(token, start + 1);
1369                int secdot = -1;
1370    
1371                if (firstdot != -1) {
1372                    secdot = datestr.indexOf(token, firstdot + 1);
1373                }
1374    
1375                int day = 0;
1376                int mon = 0;
1377                int year = 0;
1378    
1379                if (secdot != -1) { // day, mon, year
1380                    if (iso) {
1381                        year = Integer.parseInt(datestr.substring(start, firstdot));
1382                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
1383                        day = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
1384                    } else {
1385                        day = Integer.parseInt(datestr.substring(start, firstdot));
1386                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
1387                        year = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
1388                    }
1389                } else {
1390                    if (firstdot != -1) { // mon, year
1391                        if (iso) {
1392                            year = Integer.parseInt(datestr.substring(start, firstdot));
1393                            mon = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length())) - 1;
1394                        } else {
1395                            mon = Integer.parseInt(datestr.substring(start, firstdot)) - 1;
1396                            year = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length()));
1397                        }
1398    
1399                        if (last) {
1400                            if (mon <= 11) {
1401                                day = 30;
1402                            } else {
1403                                day = 5;
1404                            }
1405                        } else {
1406                            day = 1;
1407                        }
1408                    } else { // year
1409                        year = Integer.parseInt(datestr.substring(start, datestr.length()));
1410    
1411                        if (last) {
1412                            mon = 12;
1413                            day = 5;
1414                        } else {
1415                            mon = 0;
1416                            day = 1;
1417                        }
1418                    }
1419                }
1420                // test of the monthly
1421                if (mon > 12 || mon < 0)
1422                    throw new MCRException("The month of the date is inadmissible.");
1423                // Test of the daily
1424                if (day > 30 || (day < 1) || (day > 6 && mon == 12))
1425                    throw new MCRException("The day of the date is inadmissible.");
1426                if (bc)
1427                    year = -year + 1; // if before Christi
1428                EthiopicCalendar ecal = new EthiopicCalendar();
1429                ecal.set(year, mon, day);
1430    
1431                ecal.add(Calendar.DATE, 0); // Calendar correction
1432    
1433                return ecal;
1434    
1435            } catch (Exception e) {
1436                throw new MCRException("The ancient ethiopic date is false.", e);
1437            }
1438        }
1439    
1440        /**
1441         * This method convert a BuddhistCalendar date to a IslamicCalendar value.
1442         * The syntax for the buddhist input is: <br />
1443         * <ul>
1444         * <li> [-][[[t]t.][m]m.][yyy]y [B.E.]</li>
1445         * <li> [-] [[[t]t.][m]m.][yyy]y</li>
1446         * <li> [-] y[yyy][-m[m][-t[t]]] [B.E.]</li>
1447         * <li> [-] y[yyy][-m[m][-t[t]]]</li>
1448         * </ul>
1449         * 
1450         * @param datestr
1451         *            the date as string.
1452         * @param last
1453         *            the value is true if the date should be filled with the
1454         *            highest value of month or day like 12 or 31 else it fill the
1455         *            date with the lowest value 1 for month and day.
1456         * 
1457         * @return the BuddhistCalendar date value or null if an error was occurred.
1458         * @exception a
1459         *                MCRException if parsing has an error
1460         */
1461    
1462        private static final BuddhistCalendar getCalendarFromBuddhistDate(String datestr, boolean last) {
1463            try {
1464                datestr = datestr.trim();
1465                // test before Buddhas
1466                boolean bb = false;
1467                int start = 0;
1468                int ende = datestr.length();
1469                if (datestr.substring(0, 1).equals("-")) {
1470                    bb = true;
1471                    start = 1;
1472                    datestr = datestr.substring(start).trim();
1473                    ende = datestr.length();
1474                }
1475                start = 0;
1476                if (datestr.length() > 4) {
1477                    int i = datestr.indexOf("B.E.");
1478                    if (i != -1) {
1479                        start = 0;
1480                        ende = i;
1481                    }
1482                }
1483                datestr = datestr.substring(start, ende).trim();
1484    
1485                // german oder ISO?
1486                start = 0;
1487                boolean iso = false;
1488                String token = ".";
1489    
1490                if (datestr.indexOf("-", start + 1) != -1) {
1491                    iso = true;
1492                    token = "-";
1493                }
1494                // 
1495                int firstdot = datestr.indexOf(token, start + 1);
1496                int secdot = -1;
1497    
1498                if (firstdot != -1) {
1499                    secdot = datestr.indexOf(token, firstdot + 1);
1500                }
1501    
1502                int day = 0;
1503                int mon = 0;
1504                int year = 0;
1505    
1506                if (secdot != -1) { // day, month, year
1507                    if (iso) {
1508                        year = Integer.parseInt(datestr.substring(start, firstdot));
1509                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
1510                        day = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
1511                    } else {
1512                        day = Integer.parseInt(datestr.substring(start, firstdot));
1513                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
1514                        year = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
1515                    }
1516                } else {
1517                    if (firstdot != -1) { // month, year
1518                        if (iso) {
1519                            year = Integer.parseInt(datestr.substring(start, firstdot));
1520                            mon = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length())) - 1;
1521                        } else {
1522                            mon = Integer.parseInt(datestr.substring(start, firstdot)) - 1;
1523                            year = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length()));
1524                        }
1525    
1526                        if (last) {
1527                            if (mon == 0 || mon == 2 || mon == 4 || mon == 6 || mon == 7 || mon == 9 || mon == 11) {
1528                                day = 31;
1529                            }
1530                            if (mon == 1) {
1531                                day = 28;
1532                            }
1533                            if (mon == 3 || mon == 5 || mon == 8 || mon == 10) {
1534                                day = 30;
1535                            }
1536                        } else {
1537                            day = 1;
1538                        }
1539                    } else { // year
1540                        year = Integer.parseInt(datestr.substring(start, datestr.length()));
1541    
1542                        if (last) {
1543                            mon = 11;
1544                            day = 29;
1545                        } else {
1546                            mon = 0;
1547                            day = 1;
1548                        }
1549                    }
1550                }
1551                BuddhistCalendar budcal = new BuddhistCalendar();
1552                // test of the monthly
1553                if (mon > 11 || mon < 0) {
1554                    throw new MCRException("The month of the date is inadmissible.");
1555                }
1556    
1557                // Test of the daily
1558                if (((mon == 0 || mon == 2 || mon == 4 || mon == 6 || mon == 7 || mon == 9 || mon == 11) && day > 31) || ((mon == 3 || mon == 5 || mon == 8 || mon == 10) && day > 30) || (mon == 1 && day > 29 && year % 4 == 0) || (mon == 1 && day > 28 && year % 4 > 0) || day < 1) {
1559                    throw new MCRException("The day of the date is inadmissible.");
1560                }
1561                if (bb)
1562                    year = -year + 1; // if before Buddha
1563    
1564                if (year == 2125 && mon == 9 && day >= 5 && day < 15) {
1565                    day = 15;
1566                }
1567    
1568                budcal.set(year, mon, day);
1569                return (BuddhistCalendar) budcal;
1570            } catch (Exception e) {
1571                throw new MCRException("The ancient buddhist date is false.", e);
1572            }
1573        }
1574    
1575        /**
1576         * This method convert a PersicCalendar date to a GregorianCalendar value.
1577         * The The syntax for the persian input is: <br />
1578         * <ul>
1579         * <li> [-] [[[t]t.][m]m.][yyy]y</li>
1580         * <li> [-] y[yyy][-m[m][-t[t]]]</li>
1581         * </ul>
1582         * 
1583         * @param datestr
1584         *            the date as string.
1585         * @param last
1586         *            the value is true if the date should be filled with the
1587         *            highest value of month or day like 13 or 30 else it fill the
1588         *            date with the lowest value 1 for month and day.
1589         * 
1590         * @return the GregorianCalendar date value or null if an error was
1591         *         occurred.
1592         * @exception a
1593         *                MCRException if parsing has an error
1594         */
1595        private static final GregorianCalendar getCalendarFromPersicDate(String datestr, boolean last) {
1596            try {
1597                datestr = datestr.trim();
1598                // test before
1599                boolean bb = false;
1600                int start = 0;
1601                int ende = datestr.length();
1602                if (datestr.substring(0, 1).equals("-")) {
1603                    bb = true;
1604                    start = 1;
1605                    datestr = datestr.substring(start).trim();
1606                    ende = datestr.length();
1607                }
1608    
1609                // german or ISO?
1610                start = 0;
1611                boolean iso = false;
1612                String token = ".";
1613    
1614                if (datestr.indexOf("-", start + 1) != -1) {
1615                    iso = true;
1616                    token = "-";
1617                }
1618    
1619                int firstdot = datestr.indexOf(token, start + 1);
1620                int secdot = -1;
1621    
1622                if (firstdot != -1) {
1623                    secdot = datestr.indexOf(token, firstdot + 1);
1624                }
1625    
1626                int day = 0;
1627                int mon = 0;
1628                int year = 0;
1629    
1630                if (secdot != -1) { // year, month, day
1631                    if (iso) {
1632                        year = Integer.parseInt(datestr.substring(start, firstdot));
1633                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
1634                        day = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
1635                    } else {
1636                        day = Integer.parseInt(datestr.substring(start, firstdot));
1637                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot)) - 1;
1638                        year = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
1639                    }
1640                } else {
1641                    if (firstdot != -1) { // year, month
1642                        if (iso) {
1643                            year = Integer.parseInt(datestr.substring(start, firstdot));
1644                            mon = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length())) - 1;
1645                        } else {
1646                            mon = Integer.parseInt(datestr.substring(start, firstdot)) - 1;
1647                            year = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length()));
1648                        }
1649    
1650                        if (last) {
1651                            if (mon == 0 || mon == 1 || mon == 2 || mon == 3 || mon == 4 || mon == 5) {
1652                                day = 31;
1653                            }
1654                            if (mon == 6 || mon == 7 || mon == 8 || mon == 9 || mon == 10) {
1655                                day = 30;
1656                            }
1657                            if (mon == 11) {
1658                                day = 29;
1659                            }
1660    
1661                        } else {
1662                            day = 1;
1663                        }
1664                    } else { // year
1665                        year = Integer.parseInt(datestr.substring(start, datestr.length()));
1666    
1667                        if (last) {
1668                            mon = 11;
1669                            day = 29;
1670                        } else {
1671                            mon = 0;
1672                            day = 1;
1673                        }
1674                    }
1675                }
1676                int njahr = 0;
1677                if (bb)
1678                    year = -year + 1;
1679                njahr = year + 621;
1680    
1681                GregorianCalendar newdate = new GregorianCalendar();
1682                newdate.set(njahr, 2, 20); // yearly beginning to 20.3.
1683                // beginning of the month (day to year)
1684                int begday = 0;
1685                if (mon == 1)
1686                    begday = 31;
1687                if (mon == 2)
1688                    begday = 62;
1689                if (mon == 3)
1690                    begday = 93;
1691                if (mon == 4)
1692                    begday = 124;
1693                if (mon == 5)
1694                    begday = 155;
1695                if (mon == 6)
1696                    begday = 186;
1697                if (mon == 7)
1698                    begday = 216;
1699                if (mon == 8)
1700                    begday = 246;
1701                if (mon == 9)
1702                    begday = 276;
1703                if (mon == 10)
1704                    begday = 306;
1705                if (mon == 11)
1706                    begday = 336;
1707                begday += day - 1;
1708    
1709                int jh = njahr / 100; // century
1710                int b = jh % 4;
1711                int c = njahr % 100; // year of the century
1712                int d = c / 4; // count leap year of the century
1713    
1714                int min;
1715                if (njahr >= 0) {
1716                    min = b * 360 + 350 * c - d * 1440 + 720; // minute
1717                    newdate.add(Calendar.MINUTE, min); // minute of day
1718                    newdate.add(Calendar.DATE, begday); // day of the year
1719                } else {
1720                    min = b * 360 + 350 * c - d * 1440 + 720; // minute
1721                    newdate.add(Calendar.DATE, begday + 2); // day of the year
1722                    newdate.add(Calendar.MINUTE, min); // minute of day
1723                }
1724    
1725                // problem 1582
1726                year = newdate.get(Calendar.YEAR);
1727                mon = newdate.get(Calendar.MONTH) + 1;
1728                if (year == 1582 && mon == 10 && day >= 5 && day < 15) {
1729                    newdate.set(year, mon - 1, 15);
1730                }
1731    
1732                return newdate;
1733    
1734            } catch (Exception e) {
1735                throw new MCRException("The ancient persian date is false.", e);
1736            }
1737        }
1738    
1739        /**
1740         * This method convert a ArmenianCalendar date to a GregorianCalendar value.
1741         * The syntax for the Armenian input is [-][[t]t.][m]m.][yyy]y] or
1742         * [-][[yyy]y-[[m]m]-[[t]t].
1743         * 
1744         * <ul>
1745         * <li> [-] [[[t]t.][m]m.][yyy]y</li>
1746         * <li> [-] y[yyy][-m[m][-t[t]]]</li>
1747         * </ul>
1748         * 
1749         * @param datestr
1750         *            the date as string.
1751         * @param last
1752         *            the value is true if the date should be filled with the
1753         *            highest value of month or day like 13 or 30 else it fill the
1754         *            date with the lowest value 1 for month and day.
1755         * 
1756         * @return the GregorianCalendar date value or null if an error was
1757         *         occurred.
1758         * @exception a
1759         *                MCRException if parsing has an error
1760         */
1761        private static final GregorianCalendar getCalendarFromArmenianDate(String datestr, boolean last) {
1762            try {
1763                datestr = datestr.trim();
1764                // test before
1765                boolean ba = false;
1766                int start = 0;
1767                int ende = datestr.length();
1768                if (datestr.substring(0, 1).equals("-")) {
1769                    ba = true;
1770                    start = 1;
1771                    datestr = datestr.substring(start).trim();
1772                    ende = datestr.length();
1773                }
1774    
1775                // german or ISO?
1776                start = 0;
1777                boolean iso = false;
1778                String token = ".";
1779    
1780                if (datestr.indexOf("-", start + 1) != -1) {
1781                    iso = true;
1782                    token = "-";
1783                }
1784    
1785                int firstdot = datestr.indexOf(token, start + 1);
1786                int secdot = -1;
1787    
1788                if (firstdot != -1) {
1789                    secdot = datestr.indexOf(token, firstdot + 1);
1790                }
1791                int day = 0;
1792                int mon = 0;
1793                int year = 0;
1794    
1795                if (secdot != -1) { // year, month, day
1796                    if (iso) {
1797                        year = Integer.parseInt(datestr.substring(start, firstdot));
1798                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot));
1799                        day = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
1800                    } else {
1801                        day = Integer.parseInt(datestr.substring(start, firstdot));
1802                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot));
1803                        year = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
1804                    }
1805                } else {
1806                    if (firstdot != -1) { // year, month
1807                        if (iso) {
1808                            year = Integer.parseInt(datestr.substring(start, firstdot));
1809                            mon = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length()));
1810                        } else {
1811                            mon = Integer.parseInt(datestr.substring(start, firstdot));
1812                            year = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length()));
1813                        }
1814    
1815                        if (last) {
1816                            if (mon <= 12)
1817                                day = 30;
1818                            if (mon == 13)
1819                                day = 5;
1820                        } else {
1821                            mon = 1;
1822                            day = 1;
1823                        }
1824                    } else { // year
1825                        year = Integer.parseInt(datestr.substring(start, datestr.length()));
1826    
1827                        if (last) {
1828                            mon = 13;
1829                            day = 5;
1830                        } else {
1831                            mon = 1;
1832                            day = 1;
1833                        }
1834                    }
1835                }
1836                // test of the monthly
1837                if (mon > 13 || mon < 1)
1838                    throw new MCRException("The month of the date is inadmissible.");
1839                // Test of the daily
1840                if (day > 30 || (day < 1) || (day > 5 && mon == 13))
1841                    throw new MCRException("The day of the date is inadmissible.");
1842                int difyear;
1843                int difday;
1844                int jhd = 1600;
1845                int ndifday = 0;
1846                if (ba)
1847                    year = -year + 1;
1848                GregorianCalendar ecal = new GregorianCalendar();
1849                if ((year * 10000 + mon * 100 + day) >= 10311214) {// Jahr >
1850                    // 14.12.1031
1851                    difyear = year - 1031;
1852                    difday = (difyear * 365) + (mon - 1) * 30 + day - 344;
1853                    ecal.set(1582, 9, 15);
1854                    ecal.add(Calendar.DATE, difday);
1855                }
1856                if ((year * 10000 + mon * 100 + day) < 10311214 && (year * 10000 + mon * 100 + day) > 10311204) { // 
1857                    ecal.set(1582, 9, 15);
1858                }
1859                if ((year * 10000 + mon * 100 + day) <= 10311204) {// Jahr <
1860                    // 5.10.1592
1861                    ecal.set(1582, 9, 15);
1862                    difyear = year - 1031;
1863                    int daysyear = 36525;
1864                    difday = (difyear * 365) + (mon - 1) * 30 + day - 334;
1865    
1866                    if (difday <= -30168) {
1867                        ndifday = ndifday - 30168;
1868                        jhd = 1500;
1869                        difday = difday + 30167;
1870                        while (difday < 0) {
1871                            if (difday < -daysyear) { // 36525
1872                                ndifday = ndifday - daysyear;
1873                                jhd = jhd - 100;
1874                                if (jhd == 0)
1875                                    jhd = -1;
1876                                if (jhd == -1) {
1877                                    jhd = 0;
1878                                } else {
1879                                    daysyear = 36525;
1880                                }
1881                                if (jhd % 400 == 0) {
1882                                    difday = difday + daysyear;
1883                                } else {
1884                                    difday = difday + daysyear - 1;
1885                                }
1886                            } else {
1887                                ndifday = ndifday + difday;
1888                                difday = 0;
1889                            }
1890                        }
1891                        ecal.add(Calendar.DATE, ndifday);
1892                    } else {
1893                        ecal.add(Calendar.DATE, difday);
1894                    }
1895                }
1896                return ecal;
1897    
1898            } catch (Exception e) {
1899                throw new MCRException("The ancient armenian date is false.", e);
1900            }
1901        }
1902    
1903        /**
1904         * This method convert a EgyptianCalendar date to a GregorianCalendar value.
1905         * The The syntax for the egyptian (Nabonassar) input is: <br />
1906         * <ul>
1907         * <li> [-][[[t]t.][m]m.][yyy]y [A.N.]</li>
1908         * <li> [-] [[[t]t.][m]m.][yyy]y</li>
1909         * <li> [-] y[yyy][-m[m][-t[t]]] [A.N.]</li>
1910         * <li> [-] y[yyy][-m[m][-t[t]]]</li>
1911         * </ul>
1912         * 
1913         * @param datestr
1914         *            the date as string.
1915         * @param last
1916         *            the value is true if the date should be filled with the
1917         *            highest value of month or day like 13 or 30 else it fill the
1918         *            date with the lowest value 1 for month and day.
1919         * 
1920         * @return the GregorianCalendar date value or null if an error was
1921         *         occurred.
1922         * @exception a
1923         *                MCRException if parsing has an error
1924         */
1925        private static final GregorianCalendar getCalendarFromEgyptianDate(String datestr, boolean last) {
1926            try {
1927                datestr = datestr.trim();
1928                // test before
1929                boolean ba = false;
1930                int start = 0;
1931                int ende = datestr.length();
1932                if (datestr.substring(0, 1).equals("-")) {
1933                    ba = true;
1934                    start = 1;
1935                    datestr = datestr.substring(start).trim();
1936                    ende = datestr.length();
1937                }
1938                start = 0;
1939                if (datestr.length() > 4) {
1940                    int i = datestr.indexOf("A.N.");
1941                    if (i != -1) {
1942                        start = 0;
1943                        ende = i;
1944                    }
1945                }
1946                datestr = datestr.substring(start, ende).trim();
1947                // german or ISO?
1948                start = 0;
1949                boolean iso = false;
1950                String token = ".";
1951    
1952                if (datestr.indexOf("-", start + 1) != -1) {
1953                    iso = true;
1954                    token = "-";
1955                }
1956    
1957                int firstdot = datestr.indexOf(token, start + 1);
1958                int secdot = -1;
1959    
1960                if (firstdot != -1) {
1961                    secdot = datestr.indexOf(token, firstdot + 1);
1962                }
1963    
1964                int day = 0;
1965                int mon = 0;
1966                int year = 0;
1967    
1968                if (secdot != -1) { // year, month, day
1969                    if (iso) {
1970                        year = Integer.parseInt(datestr.substring(start, firstdot));
1971                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot));
1972                        day = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
1973                    } else {
1974                        day = Integer.parseInt(datestr.substring(start, firstdot));
1975                        mon = Integer.parseInt(datestr.substring(firstdot + 1, secdot));
1976                        year = Integer.parseInt(datestr.substring(secdot + 1, datestr.length()));
1977                    }
1978                } else {
1979                    if (firstdot != -1) { // year, month
1980                        if (iso) {
1981                            year = Integer.parseInt(datestr.substring(start, firstdot));
1982                            mon = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length()));
1983                        } else {
1984                            mon = Integer.parseInt(datestr.substring(start, firstdot));
1985                            year = Integer.parseInt(datestr.substring(firstdot + 1, datestr.length()));
1986                        }
1987    
1988                        if (last) {
1989                            if (mon <= 12)
1990                                day = 30;
1991                            if (mon == 13)
1992                                day = 5;
1993                        } else {
1994                            mon = 1;
1995                            day = 1;
1996                        }
1997                    } else { // year
1998                        year = Integer.parseInt(datestr.substring(start, datestr.length()));
1999    
2000                        if (last) {
2001                            mon = 13;
2002                            day = 5;
2003                        } else {
2004                            mon = 1;
2005                            day = 1;
2006                        }
2007                    }
2008                }
2009                // test of the monthly
2010                if (mon > 13 || mon < 1)
2011                    throw new MCRException("The month of the date is inadmissible.");
2012                // Test of the daily
2013                if (day > 30 || (day < 1) || (day > 5 && mon == 13))
2014                    throw new MCRException("The day of the date is inadmissible.");
2015                int difyear;
2016                int difday;
2017                int jhd = 1600;
2018                int ndifday = 0;
2019                if (ba)
2020                    year = -year + 1;
2021                GregorianCalendar ecal = new GregorianCalendar();
2022                if ((year * 10000 + mon * 100 + day) >= 23310314) {// Jahr >
2023                    // 15.10.1592
2024                    difyear = year - 2331;
2025                    difday = (difyear * 365) + (mon - 1) * 30 + day - 74;
2026                    ecal.set(1582, 9, 15);
2027                    ecal.add(Calendar.DATE, difday);
2028                }
2029    
2030                if ((year * 10000 + mon * 100 + day) < 23310314 && (year * 10000 + mon * 100 + day) >= 23310304) { // 
2031                    ecal.set(1582, 9, 15);
2032                }
2033                if ((year * 10000 + mon * 100 + day) < 23310304) {// Jahr <
2034                    // 5.10.1592
2035                    ecal.set(1582, 9, 15);
2036                    difyear = year - 2331;
2037                    int daysyear = 36525;
2038                    difday = (difyear * 365) + ((mon - 1) * 30 + day) - 64;
2039    
2040                    if (difday <= -30168) {
2041                        ndifday = ndifday - 30168;
2042                        jhd = 1500;
2043                        difday = difday + 30167;
2044                        while (difday < 0) {
2045                            if (difday < -daysyear) { // days of 100 years 36525
2046                                ndifday = ndifday - daysyear;
2047                                jhd = jhd - 100;
2048                                if (jhd == 0)
2049                                    jhd = -1;
2050                                if (jhd == -1) {
2051                                    jhd = 0;
2052                                }
2053                                // else {daysyear=36525;
2054                                // }
2055                                if (jhd % 400 == 0) {
2056                                    difday = difday + daysyear;
2057                                } else {
2058                                    difday = difday + daysyear - 1;
2059                                }
2060                            } else {
2061                                ndifday = ndifday + difday;
2062                                difday = 0;
2063                            }
2064                        }
2065                        ecal.add(Calendar.DATE, ndifday);
2066                    } else {
2067                        ecal.add(Calendar.DATE, difday);
2068                    }
2069                }
2070                return ecal;
2071    
2072            } catch (Exception e) {
2073                throw new MCRException("The ancient egyptian date is false.", e);
2074            }
2075        }
2076    
2077        /**
2078         * This method return the Julian Day number for a given Calendar instance.
2079         * 
2080         * @param date
2081         *            an instance of a Calendar
2082         * @return the Julian Day number
2083         */
2084        public static final int getJulianDayNumber(Calendar date) {
2085            return date.get(Calendar.JULIAN_DAY);
2086        }
2087    
2088        /**
2089         * This method returns the date as string in format 'dd.MM.yyyy G'.
2090         * 
2091         * @param date
2092         *            the GregorianCalendar date
2093         * 
2094         * @return the date string
2095         */
2096        public static final String getDateToFormattedString(Calendar date) {
2097            return getDateToFormattedString(date, "dd.MM.yyyy G");
2098        }
2099    
2100        /**
2101         * This method returns the date as string.
2102         * 
2103         * @param date
2104         *            the GregorianCalendar date
2105         * @param format
2106         *            the format of the date as String
2107         * 
2108         * @return the date string in the format. If the format is wrong dd.MM.yyyy
2109         *         G is set. If the date is wrong an empty string will be returned.
2110         */
2111        public static final String getDateToFormattedString(Calendar date, String format) {
2112            if ((date == null) || (format == null) || (format.trim().length() == 0)) {
2113                return "";
2114            }
2115            SimpleDateFormat formatter = null;
2116            try {
2117                formatter = new SimpleDateFormat(format, (new Locale("en")));
2118            } catch (Exception e) {
2119                formatter = new SimpleDateFormat("dd.MM.yyyy G", (new Locale("en")));
2120            }
2121            try {
2122                formatter.setCalendar(date);
2123                return formatter.format(date.getTime());
2124            } catch (Exception e) {
2125                return "";
2126            }
2127        }
2128    
2129    }