You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在MSBuild .targets文件中获取Unix时间戳报错,求正确实现方式

在C++项目中通过MSBuild注入Unix时间戳预定义的问题解决

问题描述

尝试在C++项目的MSBuild .targets文件中,将构建时的Unix时间戳(自Unix纪元起始的秒数)作为预处理器定义注入。其中BUILD_YEAR可正常工作,但BUILD_DATETIME的写法报错,提示Subtract方法不存在或为静态方法。期望用当前方式实现,而非处理__TIME__的方案。

报错信息

Invalid static method invocation syntax: ".Subtract([System.DateTime]::UnixEpoch).TotalSeconds". Method 'System.DateTime.Subtract' not found. Static method invocation should be of the form: $([FullTypeName]::Method()), e.g. $([System.IO.Path]::Combine(a, b)). Check that all parameters are defined, are of the correct type, and are specified in the right order.

原代码

<Project ToolsVersion="16.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>  
        <!-- All Builds -->
        <BUILD_YEAR>$([System.DateTime]::Now.ToString("yyyy"))</BUILD_YEAR>
        <BUILD_DATETIME>$([System.DateTime]::Now.Subtract([System.DateTime]::UnixEpoch).TotalSeconds)</BUILD_DATETIME>
    </PropertyGroup>

    <ItemGroup>
        <!-- Note: This will ultimately come from the same path as Version.rc -->
        <ClCompile>
            <PreprocessorDefinitions>BUILD_YEAR="$(BUILD_YEAR)";BUILD_DATETIME=$(BUILD_DATETIME);%(PreprocessorDefinitions)</PreprocessorDefinitions>
        </ClCompile>
    </ItemGroup>
</Project>

问题原因与解决方案

MSBuild的属性函数语法不支持C#式的链式调用,无法直接对方法返回值连续调用其他方法。以下是两种可行的解决方式:

方案1:使用DateTimeOffset直接获取Unix时间戳(推荐)

借助System.DateTimeOffset的ToUnixTimeSeconds()方法可以直接得到秒级Unix时间戳,写法简洁且符合MSBuild语法:

<PropertyGroup>
    <BUILD_YEAR>$([System.DateTime]::Now.ToString("yyyy"))</BUILD_YEAR>
    <BUILD_DATETIME>$([System.DateTimeOffset]::Now.ToUnixTimeSeconds())</BUILD_DATETIME>
</PropertyGroup>

方案2:拆分链式调用为多步计算(兼容旧版MSBuild)

如果需要兼容不支持DateTimeOffset的旧版MSBuild,可以将计算步骤拆分,通过静态方法调用实现:

<PropertyGroup>
    <BUILD_YEAR>$([System.DateTime]::Now.ToString("yyyy"))</BUILD_YEAR>
    <BUILD_NOW>$([System.DateTime]::Now)</BUILD_NOW>
    <!-- 通过静态方法计算时间差 -->
    <BUILD_TIMESPAN>$([System.TimeSpan]::FromTicks($([System.DateTime]::Subtract($(BUILD_NOW), [System.DateTime]::UnixEpoch))))</BUILD_TIMESPAN>
    <!-- 取整得到秒级时间戳 -->
    <BUILD_DATETIME>$([System.Math]::Floor($(BUILD_TIMESPAN).TotalSeconds))</BUILD_DATETIME>
</PropertyGroup>

注意事项

  • BUILD_DATETIME是数值类型,预定义时无需加引号,原代码中的写法正确。
  • DateTimeOffset.ToUnixTimeSeconds()需要.NET Framework 4.6+或.NET Core环境,对应MSBuild 15.0及以上版本支持。

内容的提问来源于stack exchange,提问作者pjcard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 17:04:56