/* * [Age.java] * * Summary: Calculate Age from birthdate. * * Copyright: (c) 2005-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.0 2005-03-19 */ package com.mindprod.htmlmacros.macro; import com.mindprod.common18.BigDate; import com.mindprod.fastcat.FastCat; import java.text.DecimalFormat; import static java.lang.System.*; /** * Calculate Age from birthdate. * * @author Roedy Green, Canadian Mind Products * @version 1.0 2005-03-19 * @see com.mindprod.common18.Age * @since 2005-03-19 */ @SuppressWarnings( { "UnusedDeclaration" } ) public final class Age extends Macro { /** * how to use the macro */ private static final String USAGE = "\nAge macro needs date yyyy-mm-dd[BC] [on yyyy-mm-ddAD] [centuries/decades/years/months/days/puredays] Trailing BC ok, but not missing mm-dd"; /** * Template for comma. */ private static final DecimalFormat DF0 = new DecimalFormat( "###,##0" ); /** * guts of Age macro expansion * * @param birthDate person's birth date whose age you want expanded * @param onDate usually today, date on which to compute the age. * @param granularity -3 = centuries, -2= decades, -1 = years without wording 0=years 1=months 2=days * * @return age in spelled out in centuries, decades, years, months, days as requsened */ private String expand( BigDate birthDate, BigDate onDate, int granularity ) { // usually OnDate >= birthDate , but for future elapsed time to some future date, OnDate < birthDate; final int[] ymd = BigDate.age( birthDate, onDate ); int ageInYears = ymd[ 0 ]; int ageInDecades = ( ageInYears + 5 ) / 10; int ageInCenturies = ( ageInYears + 50 ) / 100; int ageInMonths = ymd[ 1 ]; int ageInDays = ymd[ 2 ]; switch ( granularity ) { case -3: ageInDecades = 0; ageInYears = 0; ageInMonths = 0; ageInDays = 0; break; case -2: ageInCenturies = 0; ageInYears = 0; ageInMonths = 0; ageInDays = 0; break; case -1: case 0: ageInCenturies = 0; ageInDecades = 0; ageInMonths = 0; ageInDays = 0; break; case 1: ageInCenturies = 0; ageInDecades = 0; ageInDays = 0; break; case 2: ageInCenturies = 0; ageInDecades = 0; break; case 3: ageInCenturies = 0; ageInDecades = 0; ageInYears = 0; ageInMonths = 0; ageInDays = onDate.getOrdinal() - birthDate.getOrdinal(); break; } final FastCat sb = new FastCat( 16 ); if ( ageInCenturies != 0 ) { sb.append( "" ); sb.append( DF0.format( ageInCenturies ) ); sb.append( " " ); if ( ageInCenturies > 1 ) { sb.append( "centuries" ); } else { sb.append( "century" ); } } if ( ageInDecades != 0 ) { sb.append( "" ); sb.append( DF0.format( ageInDecades ) ); sb.append( " decade" ); if ( ageInDecades > 1 ) { sb.append( "s" ); } } if ( ageInYears != 0 ) { sb.append( "" ); sb.append( DF0.format( ageInYears ) ); sb.append( "" ); if ( granularity != -1 ) { sb.append( " year" ); if ( ageInYears > 1 ) { sb.append( "s" ); } } } if ( ageInMonths != 0 ) { if ( ageInYears != 0 ) { if ( ageInDays != 0 ) { sb.append( ", " ); } else { sb.append( " and " ); } } sb.append( "" ); sb.append( ageInMonths ); sb.append( " month" ); if ( ageInMonths > 1 ) { sb.append( "s" ); } } if ( ageInDays != 0 ) { if ( ageInYears != 0 || ageInMonths != 0 ) { sb.append( " and " ); } sb.append( "" ); sb.append( ageInDays ); sb.append( " day" ); if ( ageInDays > 1 ) { sb.append( "s" ); } } return sb.toString(); } /** * Generate Age from birthdate . expands to age in years. or * Date can be in future. * days = year month days * puredate = ordinal diff days. * * @param parms date as ISO string. * @param quiet true if want output suppressed. * @param verbose @return expanded macro text */ public String expandMacro( String[] parms, final boolean quiet, final boolean verbose ) { if ( !quiet ) { out.print( "A" ); } if ( !( 1 <= parms.length && parms.length <= 4 ) ) { throw new IllegalArgumentException( USAGE ); } try { final BigDate birthDate = new BigDate( parms[ 0 ] ); final BigDate onDate; final int granularityParmIndex; if ( parms.length > 2 && parms[ 1 ].equals( "on" ) ) { onDate = new BigDate( parms[ 2 ] ); granularityParmIndex = 3; } else { onDate = Global.TODAY; granularityParmIndex = 1; } final int granularity; if ( parms.length > granularityParmIndex ) { final String units = parms[ granularityParmIndex ]; if ( units.equalsIgnoreCase( "centuries" ) ) { granularity = -3; } else if ( units.equalsIgnoreCase( "decades" ) ) { granularity = -2; } else if ( units.equalsIgnoreCase( "years" ) ) { granularity = 0; } else if ( units.equalsIgnoreCase( "months" ) ) { granularity = 1; } else if ( units.equalsIgnoreCase( "days" ) ) { granularity = 2; } else if ( units.equalsIgnoreCase( "puredays" ) ) { granularity = 3; } else { throw new IllegalArgumentException( USAGE ); } } else { granularity = -1; // years without wording } return expand( birthDate, onDate, granularity ); } catch ( StringIndexOutOfBoundsException e ) { throw new IllegalArgumentException( USAGE ); } catch ( NumberFormatException e ) { throw new IllegalArgumentException( USAGE ); } } }