如何更新PowerShell日期变量中的年份

huangapple go评论71阅读模式
英文:

How to update the year in a PowerShell Date Variable

问题

如何在Powershell中仅更新现有日期变量的年份?我一直在尝试更新PowerShell日期变量的年份,但我尚未成功。

我尝试发布了最小的代码,根据一些答案,我发布的代码太简单了。我在我的实际代码中没有使用Get-Date。我有几个具有无效年份(如1058年)的日期以及一些具有1059年的其他日期。所有这些都需要更新为有效的年份,我选择将它们更新为1900年,但我找不到如何做到这一点。

PS> $DateUpdateYear = Get-Date # 这实际上是一个在PowerShell中使用Import-Csv导入的csv文件中的日期。我有73,000条记录,其中一列有错误的日期。我需要找到这些小于1900年的错误日期并将它们更新为1900年。
PS> $DateUpdateYear.Year
输出 > 2023
PS> $DateUpdateYear.Year = 1900
输出 > InvalidOperation: 'Year'是只读属性

每次我搜索如何设置年份时,我都会得到Set-Date cmdlet的结果,每次我阅读Set-Date的文档时,我都看不到任何关于如何设置现有日期的年份的信息。

我决定尝试一个看起来“好得令人难以置信”的方法,即简单地使用`$DateUpdateYear.Year = 1900`来设置年份属性,但是在尝试这样做时,错误显示属性是只读的。
英文:

How do I update only the year of an existing date variable in Powershell? I have been attempting to update the year of a PowerShell Date variable however I've not yet been successful.

I made an attempt to post minimal code and I see that based on some answers my code I posted was TOO minimal. I'm not using Get-Date in my actual code anywhere. I have several dates with invalid years such as the year 1058 and some others with the year of 1059. These all need to be updated to a valid year and I chose to update them to the year 1900 but I am not finding how to do so.

PS > $DateUpdateYear = Get-Date # This is actually a date in a csv file imported into PowerShell using Import-Csv.  I have 73k records and one column has bad dates.  I need to find these bad dates less than the year 1900 and update them to 1900.
PS > $DateUpdateYear.Year
output > 2023
PS > $DateUpdateYear.Year = 1900
output > InvalidOperation: 'Year' is a ReadOnly property

Each time I google how to set the Year I continue to get results for the Set-Date cmdlet and each time I read the documentation for Set-Date I'm not seeing anything about setting the Year of an existing date.

I decided to try what appeared to be a "Too good to be true" attempt by simply setting the Year property using $DateUpdateYear.Year = 1900 however when attempting to do this the error states that the Property is ReadOnly.

TL;DR-----------------------------------------------------------TL:DR

This answer was successfully answered and to help any others who might want to update the date of date strings via a loop prior to import into SQL Server (Express/Azure) the below will show you how to accomplish this and also show how to overcome some other obstacles importing data into SQL Server/Azure.

There were three main issues to overcome and they are as follows:

  1. End Of Line Characters were Line Feeds aka New Lines. Exported files with new lines as the end of line character are typical with Linux based systems. I discovered that many tools hate Line Feeds and so the first step of the Powershell script is to Replace the EOL Line Feed as Carriage Return Line Feeds which are the standard. LF --> CRLF
  2. The next issue is that the imported file needs a column to represent the placeholder for the Identity Column. I want/need each record after it is imported to have a unique key and so this is accomplished by simply creating the table with an Identity Column. The issue I ran in to is that the csv/tsv file being imported still needed to have the identity column in the file. I couldn't get it to import without providing knowledge of this column in the Format File and therefore the import file.
  3. The last item I needed to address was to perform some pre-import data manipulation. SQL Server Dates have a restriction where the oldest date they support is the year 1753. My file had several dates with years prior to 1753 which caused the entire record to fail. This Post and the answer to it was the solution to this final problem. And now that I have the loop in place and knowledge on how to read and update the data in these PowerShell objects I can use this to update any bad data or to perform any type of pre-import analysis.

The PowerShell Import Script

#-Import TAB Delimited File (SQL Express and Azure Examples)

#-Declare File Paths
$SourceFile = "TAB_Delimited.tsv"
$ExportFile = "TAB_Updated.tsv"
$FormatFile = "TAB_Delimited.fmt"
$ErrorFile = "TAB_Delimited_Errors.log"

#---------- 1 Add Column to the beginning of the CSV/TSV file for the Identity Column.  The Export-Csv Commandlet by default also Replaces NewLine_LF (\n) with Cariage Return Line Feed CRLF (\r\n)

#-The main purpose of the below is to add a Column at the beginning of the file as a placeholder for the Identity Column in the Staging Table.
#-The below will read the Tab Delimited file having EOL Characters as New Lines/Line Feeds \n and turn them into CRLF (Cariage Return, Line Feeds) \r\n.
#-It will also remove almost all of the double quotes it finds in the file.  The -UseQuotes option is not perfect and so we still have to clean
#- up the data Post Import and remove any Leading or Trailing Double Quotes using a SQL Update.

Import-Csv $SourceFile -Delimiter "`t" | 
Select-Object @{Name='_record_number';Expression={'999'}},* | #-Example Adding new column to End Select-Object *,@{Name='column3';Expression={'setvalue'}} 
ForEach-Object {
	if ( (![string]::IsNullOrEmpty($_.client_dob)) -and ([datetime]$_.client_dob -lt (Get-Date 1900-01-01) ) ) {
		$_.client_dob = (Get-Date $_.client_dob -Year 1900).ToString('yyyy-MM-dd')
		#-Write-Host $_.pcc_id $_.client_dob
	}
	$_
} |
Export-Csv $ExportFile -Delimiter "`t" -UseQuotes Never -NoTypeInformation


#---------- 2 Import TAB Delimited File Using Format File ---------------

$global:pass = "password"

#-Use an Import File to Bulk Import Data

bcp Database.Schema.Table IN $ExportFile `
-f $FormatFile `
-e $ErrorFile `
-S LOCALSERVERPC\SQLEXPRESS `
-U sa -P $pass `
-F 2 `
#-L 1000

----------- Or using Azure with Trusted Auth follow the below example ----------------------

#-Use an Import File to Bulk Import Data into Azure

bcp Database.Schema.Table IN $ExportFile `
-f $FormatFile `
-e $ErrorFile `
-S Server_Name_Here `
-T `
-F 2 `
#-L 2000

答案1

得分: 6

# 如何在Powershell中仅更新现有日期变量的年份?
# 你不需要这样做,你只需创建该对象的新实例并将其重新分配给一个变量:

Get-Date -Year 1900

# 假设你的日期是一个字符串,你想将其解析为一个datetime实例,只更改其年份,你仍然可以使用Get-Date,并将其作为参数传递,并在其中使用-Year参数,正如[mklement0](https://stackoverflow.com/users/45375/mklement0)在评论中指出的:

Get-Date '2023-01-01' -Year 1900

# 同样的方法不仅适用于字符串,也适用于另一个datetime实例:

$oldDate = Get-Date -Year 123
# 周六,公元0123年7月17日 下午5:20:36
$newDate = Get-Date $oldDate -Year 1900
# 周二,公元1900年7月17日 下午5:20:36
英文:

> How do I update only the year of an existing date variable in Powershell?

You don't, you just create a new instance of the object and reassign it to a variable:

Get-Date -Year 1900

Considering you had the date in a string and wanted to parse it into a datetime instance while only changing its year, you can still use Get-Date passing it as argument and using the -Year parameter as mklement0 noted in a comment:

Get-Date '2023-01-01' -Year 1900

The same would work not only for a string but for another datetime instance:

$oldDate = Get-Date -Year 123
# Saturday, July 17, 0123 5:20:36 PM
$newDate = Get-Date $oldDate -Year 1900
# Tuesday, July 17, 1900 5:20:36 PM

答案2

得分: 1

对于(几乎)任何$DateUpdateYear

$DateUpdateYear = $DateUpdateYear.AddYears(1900-$DateUpdateYear.Year)

参见DateTime.AddYears(Int32) 方法

参数

> <!-- language: lang-none -->
> value Int32
> 一定数量的年份。值参数可以是负数或正数。

英文:

For (almost) any $DateUpdateYear:

$DateUpdateYear = $DateUpdateYear.AddYears(1900-$DateUpdateYear.Year)

See DateTime.AddYears(Int32) Method:

Parameters

> <!-- language: lang-none -->
> value Int32
> A number of years. The value parameter can be negative or positive.

huangapple
  • 本文由 发表于 2023年7月18日 03:43:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76707650.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定