/// <summary> /// Determines whether the add instruction operand has a valid value. /// </summary> /// <param name="value">The string used to check whether the add instruction operand has a valid value. </param> /// <returns>True if the add instruction operand has a valid value; otherwise, false. </returns> /// <remarks> /// The test performed is not dependent on the current setting of <see cref="P:NhsCui.Toolkit.DateAndTime.NhsDate.DateType">DateType</see>. /// This means true is returned if the operand is valid, even if <see cref="P:NhsCui.Toolkit.DateAndTime.NhsDate.DateType">DateType</see> is not Exact or Approximate. /// </remarks> public static bool IsAddValid(string value) { if (value == null) { throw new ArgumentNullException("value"); } Regex shortcut = new Regex(NhsDate.ResolveAddInstructionRegExTokens(), RegexOptions.IgnoreCase); Match match = shortcut.Match(value.Replace(" ", string.Empty)); return(match.Success); }
/// <summary> /// Adds a number of months, weeks, days or years to a date. /// </summary> /// <param name="sourceDate">The date to be added to. </param> /// <param name="instruction">Add instructions such as +2w to add 2 weeks or -3m to subtract 3 months. </param> /// <remarks> /// The operand can be positive or negative; if the operand is not included, it is assumed to be positive. /// </remarks> /// <exception cref="System.ArgumentNullException">If either argument is null. /// </exception> /// <exception cref="System.InvalidOperationException">If <see cref="P:NhsCui.Toolkit.DateAndTime.NhsDate.DateType">DateType</see> /// is null. </exception> /// <exception cref="System.ArgumentException">If <see cref="P:NhsCui.Toolkit.DateAndTime.NhsDate.DateType">DateType</see> /// is <see cref="P:NhsCui.Toolkit.DateAndTime.NhsDate.Year">Year</see> and the unit in the instruction is /// not DateArithmeticResources.YearsUnit. Or if <see cref="P:NhsCui.Toolkit.DateAndTime.NhsDate.DateType">DateType</see> /// is YearMonth and the unit in the instruction is /// not DateArithmeticResources.YearsUnit or DateArithmeticResources.MonthsUnit. Or if the instruction is not /// of the expected format.</exception> /// <exception cref="NhsCui.Toolkit.DateAndTime.InvalidArithmeticSetException">If the set of letters in /// the DateArithmeticResources is not unique or if values are not each a single character long. /// </exception> /// <returns>A new NhsDate object. </returns> public static NhsDate Add(NhsDate sourceDate, string instruction) { if (instruction == null) { throw new ArgumentNullException("instruction"); } if (sourceDate == null) { throw new ArgumentNullException("sourceDate"); } // check the set of resource strings used by this method are // valid if (!CheckArithmeticSetResources()) { throw new InvalidArithmeticSetException(Resources.NhsDateResources.ArithmeticSetInvalidResources); } if (sourceDate.DateType == DateType.NullIndex) { throw new InvalidOperationException(Resources.NhsDateResources.AddNotAllowedForDateType); } if (NhsDate.IsAddValid(instruction) == false) { throw new ArgumentException(Resources.NhsDateResources.AddInstructionInvalidFormat, "instruction"); } Regex shortcut = new Regex(NhsDate.ResolveAddInstructionRegExTokens(), RegexOptions.IgnoreCase); Match match = shortcut.Match(instruction.Replace(" ", string.Empty)); if (match.Success == true) { // We need to skip the first group because with this RegEx it is always the complete string int groupNumber = 0; foreach (Group g in match.Groups) { if (groupNumber > 0) // Skip first group { foreach (Capture c in g.Captures) { int increment; if (int.TryParse(c.Value.Substring(0, c.Value.Length - 1), out increment)) { if (c.Value.EndsWith(Resources.NhsDateResources.MonthsUnit, StringComparison.OrdinalIgnoreCase) == true) { if (sourceDate.DateType == DateType.Exact || sourceDate.DateType == DateType.Approximate) { sourceDate.DateValue = sourceDate.DateValue.AddMonths(increment); } else if (sourceDate.DateType == DateType.YearMonth) { sourceDate.Year += increment / 12; sourceDate.Month += increment % 12; } else { throw new ArgumentException( string.Format(CultureInfo.CurrentCulture, Resources.NhsDateResources.AddInstructionNotAllowedForDateType, "Month", sourceDate.DateType), "instruction"); } } else if (c.Value.EndsWith(Resources.NhsDateResources.WeeksUnit, StringComparison.OrdinalIgnoreCase) == true) { if (sourceDate.DateType == DateType.Exact || sourceDate.DateType == DateType.Approximate) { // Add weeks using AddDays and multiplying number of weeks to add by 7 sourceDate.DateValue = sourceDate.DateValue.AddDays(increment * 7); } else { throw new ArgumentException( string.Format(CultureInfo.CurrentCulture, Resources.NhsDateResources.AddInstructionNotAllowedForDateType, "Week", sourceDate.DateType), "instruction"); } } else if (c.Value.EndsWith(Resources.NhsDateResources.DaysUnit, StringComparison.OrdinalIgnoreCase) == true) { if (sourceDate.DateType == DateType.Exact || sourceDate.DateType == DateType.Approximate) { sourceDate.DateValue = sourceDate.DateValue.AddDays(increment); } else { throw new ArgumentException( string.Format(CultureInfo.CurrentCulture, Resources.NhsDateResources.AddInstructionNotAllowedForDateType, "Day", sourceDate.DateType), "instruction"); } } else if (c.Value.EndsWith(Resources.NhsDateResources.YearsUnit, StringComparison.OrdinalIgnoreCase) == true) { if (sourceDate.DateType == DateType.Exact || sourceDate.DateType == DateType.Approximate) { sourceDate.DateValue = sourceDate.DateValue.AddYears(increment); } else if (sourceDate.DateType == DateType.Year || sourceDate.DateType == DateType.YearMonth) { sourceDate.Year += increment; } else { throw new ArgumentException( string.Format(CultureInfo.CurrentCulture, Resources.NhsDateResources.AddInstructionNotAllowedForDateType, "Year", sourceDate.DateType), "instruction"); } } } } } groupNumber++; } } return(sourceDate); }