Recently I worked on a project, where automatic assembly versioning of Visual Studio 2010 was applied using the AssemblyVersion attribute:
[assembly: AssemblyVersion("1.0.*")]
Testers worked with multiple application versions simultaneously, and version number (that was displayed on the application UI) was assigned to the bug report in TFS work items. To be able to determine the latest changeset for a version number, I needed the exact date and time of the build.
I found several none-official description (with minor differences) of the build date – version number conversion algorithm, like this one:
Determining the Build Date of an Assembly
I decided to create a simple utility to help the conversion in both directions.
The main part of the utility is an IValueConverter class that contains the logic for the conversion:
- using System;
- using System.Linq;
- using System.Windows.Data;
- using System.Globalization;
- namespace Version2Date
- {
- class VersionToDateConverter : IValueConverter
- {
- // based on the algorithm found:
- // Kevin Gearing's Blog – Determining the Build Date of an Assembly
- // http://dotnetfreak.co.uk/blog/archive/2004/07/08/determining-the-build-date-of-an-assembly.aspx
- #region IValueConverter Members
- public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
- {
- String result = String.Empty;
- DateTime versionDate = DateTime.MinValue;
- // check the value type and try to parse it as a date
- if ((value is String) && (DateTime.TryParseExact((String)value, Global.DateFormat,
- CultureInfo.GetCultureInfo("en"), DateTimeStyles.None, out versionDate)))
- {
- if (TimeZone.IsDaylightSavingTime(versionDate, TimeZone.CurrentTimeZone.GetDaylightChanges(versionDate.Year)))
- {
- versionDate.AddHours(-1);
- }
- TimeSpan dateDiff = versionDate – Global.StartDate;
- int dayCount = (int)dateDiff.TotalDays;
- TimeSpan dateDiffSec = dateDiff.Subtract(new TimeSpan(dayCount, 0, 0, 0));
- int secCount = (int)(dateDiffSec.TotalSeconds / 2);
- result = String.Format("1.0.{0}.{1}", dayCount, secCount);
- }
- return result;
- }
- public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
- {
- String result = String.Empty;
- if (value is String)
- {
- String[] verNums = ((String)value).Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
- int dummyInt;
- if ((verNums.Length == 4) && (verNums.ToList().TrueForAll(str => int.TryParse(str, out dummyInt))))
- {
- int dayCount = int.Parse(verNums[2]);
- int secCount = int.Parse(verNums[3]) * 2;
- DateTime versionDate = Global.StartDate.AddDays(dayCount).AddSeconds(secCount);
- if (TimeZone.IsDaylightSavingTime(versionDate, TimeZone.CurrentTimeZone.GetDaylightChanges(versionDate.Year)))
- {
- versionDate.AddHours(1);
- }
- result = versionDate.ToString(Global.DateFormat);
- }
- }
- return result;
- }
- #endregion
- }
- }
The MainWindow.xaml of the application looks like this:
- <Window x:Class="Version2Date.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:local="clr-namespace:Version2Date"
- Title="Version – Date Converter"
- Height="45" Width="400" ResizeMode="NoResize">
- <Window.Resources>
- <local:VersionToDateConverter x:Key="VersionToDate"/>
- </Window.Resources>
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto"></ColumnDefinition>
- <ColumnDefinition Width="*"></ColumnDefinition>
- <ColumnDefinition Width="*"></ColumnDefinition>
- </Grid.ColumnDefinitions>
- <TextBox Grid.Column="0" Name="VersionNumber" Text="{Binding ElementName=Date, Mode=TwoWay,
- UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True,
- Path=Text, Converter={StaticResource VersionToDate}}" MinWidth="100" MaxWidth="200"/>
- <TextBox Grid.Column="1" Name="Date" MinWidth="100" MaxWidth="200" />
- <Button Grid.Column="2" Click="GetCurrentDate" MinWidth="100" MaxWidth="200">Now</Button>
- </Grid>
- </Window>
The code behind of the XAML contains the simple event handler for the button click:
- private void GetCurrentDate(object sender, RoutedEventArgs e)
- {
- Date.Text = DateTime.Now.ToString(Global.DateFormat);
- }
The next image displays the utility in action: