How do I get the difference between two dates in a .csproj file?
Asked Answered
H

2

6

I saw some code like this, in a csproj file

$([System.DateTime]::UtcNow.ToString(mmff))

to autoincrement the assembly version:

<VersionSuffix>2.0.0.$([System.DateTime]::UtcNow.ToString(mmff))</VersionSuffix>
<AssemblyVersion Condition=" '$(VersionSuffix)' == '' ">0.0.0.1</AssemblyVersion>

What kind of language/script is that? How do I use it to get the difference between two dates?

I tried to do something like this:

<VersionMajor>2</VersionMajor>
<VersionMinor>1</VersionMinor>
<DaysFromLastRelease>$(([System.DateTime]::UtcNow - new [System.DateTime](2021,1,1))::TotalDays)</DaysFromLastRelease>

but it does not work :)

Hatti answered 12/5, 2021 at 18:42 Comment(5)
It is not a language. File is only read and is XML format.Everything
The OP is speaking of the embedded expressions like [System.DateTime]::UtcNow.ToString(mmff).Shiah
Looks a bit like PowerShellHumanoid
I would not recommend using time to produce version numbers. It can break MSBuild's incremental build model and produce longer build times.Incorrupt
Saw this example about semantic versioning. It uses git's commit info instead of timeTanner
P
6

.csproj files are basically MSBuild files (XML). The embedded syntax you are referring to is called a Property Function.

It appears that subtraction using the minus (-) might not be supported. There is a Subtract() property function in Property Functions.

Perhaps this could be the base for a solution. I have not tried it!

<Now>$([System.DateTime]::UtcNow.DayOfYear)</Now>

<January>$([System.DateTime]::new(2021,1,1)).DayOfYear</January>
<!-- or... (not sure about the below)
<January>$([System.DateTime]::Parse("1/1/2021").DayOfYear)</January>
 -->

<DaysFromLastRelease>$([MSBuild]::Subtract($(Now), $(January)))</DaysFromLastRelease>

Other possibilities

  • calculate the date difference by writing an MSBuild task
  • call out to a simple program you write
  • somehow use an external program to set an environment variable, and then reference that variable in your .csproj
Parable answered 12/5, 2021 at 19:14 Comment(9)
new DateTime could be used as e.g. $([System.DateTime]::new(2021,1,1))Haunt
@Haunt good to know. I'll add to my answer. Thanks.Parable
Is this supported by any compiler of the .NET platform (Framework and/or Core, Mono...), or only dedicated to Visual Studio?Inflammable
@OlivierRogier it's MSBuild, so presumably it would work outside of VS.Parable
DayOfAYear will only work with 1st of January then ) if I have the first day of February will not....Hatti
@Serge sorry not following you. Maybe you don't need <January> at all then...?Parable
I mean, if we put the december 2020 then it would be a negative value, because in december 2020 DayOfYear will be greater than in January or Mai 2021...Hatti
Based on the fact you have a node called DaysFromLastRelease it sounds like you are wanting to calculate Now - LastBuildDate and then get that in a # of days right? What I provided in my answer is kind of hardcoded, so that's why I said it would be a base, and not a full solution. Full solution would have to account for oddities such as a negative value. MSBuild while powerful, may have met its match in what you want to do... not sure ;)Parable
not working of DayOfYear of the last date is less than the DayOfYear of previous date (if next year)Hatti
T
5

That's what worked for me:

<PropertyGroup>
    <VersionMajor Condition="'$(VersionMajor)' == ''">0</VersionMajor>
    <VersionMinor Condition="'$(VersionMinor)' == ''">0</VersionMinor>
    <VersionPatch Condition="'$(VersionPatch)' == ''">$([System.DateTime]::UtcNow.Subtract($([System.DateTime]::new(2001,1,1))).TotalDays.ToString("0"))</VersionPatch>
    <VersionRevision Condition="'$(VersionRevision)' == ''">$([System.DateTime]::UtcNow.TimeOfDay.TotalMinutes.ToString("0"))</VersionRevision>
    <Version>$(VersionMajor).$(VersionMinor).$(VersionPatch).$(VersionRevision)</Version>
</PropertyGroup>

Here I manually set VersionMajor and VersionMinor. Then I have autoincremented values for Patch and revision.

  • Patch : number of days since 2001/01/01 (first day of century XXI).
  • Revision : total minutes of the day

That's good enought untill June 2180 (Remember máx versión number is 65534).


Extra tip: I put all this lines into a Version.Build.props file into Properties folder. Then I import it from csproj file with this tag:

<Import Project="$([MSBuild]::GetPathOfFileAbove('Version.Build.props', '$(MSBuildThisFileDirectory)/Properties/'))" />

This way, I can manually set proyect versions manually in my csproj file, left them in auto or a mix of them by just setting VersionMajor and VersionMinor which is what I actually do.

Tenure answered 21/6, 2021 at 11:38 Comment(2)
I added .Date after UtcNow - the TotalDays implementation rounds PM to the next day, which breaks the strict increasing logic <VersionPatch Condition="'$(VersionPatch)' == ''">$([System.DateTime]::UtcNow.Date.Subtract($([System.DateTime]::new(2001, 1, 1))).TotalDays.ToString("0"))</VersionPatch>Intermediate
I tested it and it works for me. My PC is set to use 24h format by default, maybe that's the point here.Zacynthus

© 2022 - 2024 — McMap. All rights reserved.