Windows 10 MP4 Media Created date/time fields are 4 hours earlier than they should be

GA Hiker

New Member
Joined
Sep 29, 2018
Messages
8
After a trip, I transferred my photos/videos from my SD camera memory card to my PC using copy/paste in Windows Explorer. The Media created date/time on the PC MP4 files are 4 hours earlier that they should be. When the Date modified is "9/24/2018 2:52 PM" the Media created date/time shows "9/24/2018 10:52 AM". For JPG files Date taken and Date modified are equal. When I try to correct the Media created date/time I am only able to change the date, not the time. Why is this happening? How can I correct it?
 
On a recent trip, my husband and I each took photos/videos which we now want to merge. Unfortunately, the times on our cameras were set an hour apart, making it impossible to sort our photos together by date/time. Is there a way to change the date/times of my 1000+ photos?
 
Some explanations would that you were in a different time zone, or the device that created the pictures/videos time was off.

You may need to use Powershell to change the time like so

 
Last edited by a moderator:
Threads merged since it's the same. Let me know the requirements for the time change and I can help write some Powershell code to correct the time.
 
Thank you for your reply. All of the photos/videos were taken in the same time zone. My camera's destination time was set to five (5) hours earlier than my home time zone (not 4). I can think of no reason why the videos are given a time, in only one of the date/time fields, that is 4 hours earlier than its other date/times and all the date/times in the photos. It certainly seems like a bug.

Although I am a retired software developer, I only learned of the existence of Powershell a couple days ago when Googling for solutions to my problem. In the past, on DOS systems, I have written many .bat files to accomplish a variety of tasks. While I follow what you have done, without a Powershell manual I don't know how, for each of a group of files, to retrieve the date/time needing change, adjust it, and replace it.
 
Threads merged since it's the same. Let me know the requirements for the time change and I can help write some Powershell code to correct the time.
I wrote my previous reply before I saw this message. What I need to do is, for each of my MP4 files, change the existing "Media created" date/time to 4 hours earlier.

After that, I assume I will be able to figure out how to modify that code to change date/times in all my photo/video files from this trip to 1 hour earlier. Embarrassed to explain that my camera was set to 5 hours earlier than home when it should have been set to 6 hours earlier. I need to correct that in order to merge my photos/videos with my husband's. His camera was correctly set to 6 hours earlier.

Thank you so much.
 
If you only need to set the the time back 1 hour this should do it. Open a powershell prompt and copy the following code and hit enter. That will load this function in the current Powershell console. Then type Set-Filetime -FilePath "C:\Path\To\Root\Directory\Of\The\Pictures" and it will set the creation time back 1 hour.

Code:
Function Set-FileTime
{
    Param
    (
        [String]$FilePath
    )

    $Files = Get-ChildItem -Path $FilePath -Recurse

    Foreach($File in $Files)
    {
        $CreationTime = Get-ItemPropertyValue -Path $File.FullName -Name "CreationTime"
        $NewCreationTime = $CreationTime.AddHours(-1)
        Set-ItemProperty -Path $File.FullName -Name "CreationTime" -Value $NewCreationTime
    }
}
 
That code alone, no thats just a function, but you can add the line to execute it at the bottom Set-Filetime -FilePath "C:\Path\To\Root\Directory\Of\The\Pictures"

Then save it as a .ps1 file. This won't execute though because Powershell relies on the execution policy which my default blocks scripts from running. You can set the execution policy with Set-ExecutionPolicy -Scope LocalMachine -ExecutionPolicy Unrestricted then you can run Powershell scripts.
 
I did exactly what you said. I opened a powershell prompt, I pasted your code to define the function and pressed enter. Then I typed:
"Set-Filetime -FilePath "C:\Users\Myname\Desktop\Testfiles"
I had 3 JPG files in the Testfiles folder. None of the times in those files changed -- not Date taken, Date created, or Date modified. I also tried it with an MP4 file -- nada. What I need to do is change the Date taken time in the JPG files and the Media created time in MP4 files. I can't believe this is such a challenge.

I also downloaded Bulk File Changer which seemed promising but didn't work either. Looks like it can change the time on a group of files but they all end up with the same time.
 
Might be a different field then. Looks like there is metadata field called DateTaken. This field isn't easy to update programmtically
 
Whew that was a bit of research and testing. This function should work.

*NOTE* I'd recommend testing on a copy to validate it works.
I also only wrote it for JPEG files, I believe it would have to be somewhat duplicated to work with other formats

After he function is loaded. Set-DateTaken -Directory "C:\Root\Of\Pictures"

Code:
Function Set-DateTaken
{
    
    [System.Reflection.Assembly]::LoadWithPartialName("PresentationCore")
    [System.Reflection.Assembly]::LoadWithPartialName("WindowsBase")
    [System.Reflection.Assembly]::LoadWithPartialName("System.Xaml")

    Param
    (
        [Parameter(Mandatory=$true)][String]$Directory
    )

    If(-not(Test-Path -Path $Directory))
    { exit }

    $Files = Get-ChildItem -Path $Directory -Recurse -Include "*.jpg","*.jpeg"

    Foreach($File in $Files)
    {
        $SourcePath = $File.FullName.Replace(".jpeg",".jpg")
        $DestinationPath = $File.FullName.Replace(".jpg","-new.jpg")
        [System.Windows.Media.Imaging.BitmapFrame]$Frame = $null

        $InputStream = [System.IO.File]::Open($SourcePath,[System.IO.FileMode]::Open,[System.IO.FileAccess]::Read)
        $Decode = [System.Windows.Media.Imaging.JpegBitmapDecoder]::Create($InputStream,[System.Windows.Media.Imaging.BitmapCreateOptions]::PreservePixelFormat,[System.Windows.Media.Imaging.BitmapCacheOption]::None)

        $Frame = $Decode.Frames[0]
        $MetaData = $Frame.Metadata.Clone()
        $DateTaken = $MetaData.DateTaken
        $NewDate = [DateTime]$DateTaken
        $NewDataTaken = $NewDate.AddHours(-1)
        $MetaData.DateTaken = $NewDataTaken


        $Encoder = New-Object System.Windows.Media.Imaging.JpegBitmapEncoder
        $Encoder.Frames.Add([System.Windows.Media.Imaging.BitmapFrame]::Create($Frame,$Frame.Thumbnail,$MetaData,$Frame.ColorContexts))


        $OutputStream = [System.IO.File]::Open($DestinationPath,[System.IO.FileMode]::Create,[System.IO.FileAccess]::ReadWrite)
        $Encoder.Save($OutputStream)

        $InputStream.Close()
        $OutputStream.Close()

        Remove-item $SourcePath
        Rename-Item $DestinationPath -NewName $SourcePath
    }
}
 
Ok so I figured because I'm kind of crazy I'd make it better... I've added a bunch of picture file types. It will handle jpg,bmp,gif,tiff,png and wmp now. It also has you specify the time increment and amount. To set it back seconds,minutes,hours etc supply it a negative value.

Example to set all the images "DateTaken" back 1 hour for "C:\Users\User\Pictures\Test", you type the following after loading the function.
Set-DateTaken -Directory "C:\Users\User\Pictures\Test" -TimeType Hours -Amount -1

New Code
Code:
Function Set-DateTaken
{
    [CmdletBinding()]

    Param
    (
        [Parameter(Mandatory=$true)][String]$Directory,
        [Parameter(Mandatory=$true)][ValidateSet("Seconds","Minutes","Hours","Days")][String]$TimeType,
        [int]$Amount=0
    )
    [System.Reflection.Assembly]::LoadWithPartialName("PresentationCore")
    [System.Reflection.Assembly]::LoadWithPartialName("WindowsBase")
    [System.Reflection.Assembly]::LoadWithPartialName("System.Xaml")

    If(-not(Test-Path -Path $Directory))
    {
        Write-Verbose "$Directory was not found, exiting..."
        exit
    }
    Else
    {
        Write-Verbose "$Directory found, proceeding..."
    }

    Write-Verbose "Grabing all image files from $Directory..."
    $Files = Get-ChildItem -Path $Directory -Recurse -Include "*.jpg","*.jpeg","*.bmp","*.dib","*.gif","*.tff","*.tif","*.wmp","*.png"

    Foreach($File in $Files)
    {
        $SourcePath = $File.FullName
        Write-Verbose "$($File.FullName) source path set to $SourcePath"
        $DestinationPath = $File.FullName.Replace($File.Extension,"-new$($File.Extension)")
        Write-Verbose "$($File.FullName) destination path set to $DestinationPath"
        [System.Windows.Media.Imaging.BitmapFrame]$Frame = $null

        Write-Verbose "Opeing IO stream to $File.Name for reading"
        $InputStream = [System.IO.File]::Open($SourcePath,[System.IO.FileMode]::Open,[System.IO.FileAccess]::Read)

        If($File.Extension -match "\.jp(|e)g")
        {
            Write-Verbose "Decoder is set to JPG based on file extension"
            $Decode = [System.Windows.Media.Imaging.JpegBitmapDecoder]::Create($InputStream,[System.Windows.Media.Imaging.BitmapCreateOptions]::PreservePixelFormat,[System.Windows.Media.Imaging.BitmapCacheOption]::None)
        }
        ElseIf($File.Extension -match "(\.bmp|\.dib)")
        {
            Write-Verbose "Decoder is set to BMP based on file extension"
            $Decode = [System.Windows.Media.Imaging.BitmapDecoder]::Create($InputStream,[System.Windows.Media.Imaging.BitmapCreateOptions]::PreservePixelFormat,[System.Windows.Media.Imaging.BitmapCacheOption]::None)
        }
        ElseIf($File.Extension -match "(\.tiff|\.tif)")
        {
            Write-Verbose "Decoder is set to TIFF based on file extension"
            $Decode = [System.Windows.Media.Imaging.TiffBitmapDecoder]::Create($InputStream,[System.Windows.Media.Imaging.BitmapCreateOptions]::PreservePixelFormat,[System.Windows.Media.Imaging.BitmapCacheOption]::None)
        }
        ElseIf($File.Extension -match "\.wmp")
        {
            Write-Verbose "Decoder is set to WMP based on file extension"
            $Decode = [System.Windows.Media.Imaging.WmpBitmapDecoder]::Create($InputStream,[System.Windows.Media.Imaging.BitmapCreateOptions]::PreservePixelFormat,[System.Windows.Media.Imaging.BitmapCacheOption]::None)
        }
        ElseIf($File.Extension -match "\.png")
        {
            Write-Verbose "Decoder is set to PNG based on file extension"
            $Decode = [System.Windows.Media.Imaging.PNGBitmapDecoder]::Create($InputStream,[System.Windows.Media.Imaging.BitmapCreateOptions]::PreservePixelFormat,[System.Windows.Media.Imaging.BitmapCacheOption]::None)
        }
        ElseIf($File.Extension -match "\.gif")
        {
            Write-Verbose "Decoder is set to GIF based on file extension"
            $Decode = [System.Windows.Media.Imaging.GIFBitmapDecoder]::Create($InputStream,[System.Windows.Media.Imaging.BitmapCreateOptions]::PreservePixelFormat,[System.Windows.Media.Imaging.BitmapCacheOption]::None)
        }

       
        $Frame = $Decode.Frames[0]
        $MetaData = $Frame.Metadata.Clone()

        <#
            Add new parameters in appropriate format for each meta dat tag
            Research all meta data fields

            Manipulate each meta data tag as needed
        #>
        $DateTaken = $MetaData.DateTaken
        If($DateTaken -eq $null)
        {
            $DateTaken = $File.CreationTime.ToString()
        }
        $NewDate = [DateTime]$DateTaken

                Switch ($TimeType)
        {
            "Seconds" { $NewDataTaken = $NewDate.AddSeconds($Amount); Break }
            "Minutes" { $NewDataTaken = $NewDate.AddMinutes($Amount); Break }
            "Hours" { $NewDataTaken = $NewDate.AddHours($Amount); Break }
            "Days" { $NewDataTaken = $NewDate.AddDays($Amount); Break }
        }
       
        $MetaData.DateTaken = $NewDataTaken

        Write-Verbose "Date Taken is now $NewDataTaken"

        If($File.Extension -match "\.jp(|e)g")
        {
            Write-Verbose "Encoder is set to JPG based on file extension"
            $Encoder = New-Object System.Windows.Media.Imaging.JpegBitmapEncoder
        }
        ElseIf($File.Extension -match "(\.bmp|\.dib)")
        {
            Write-Verbose "Encoder is set to BMP based on file extension"
            $Encoder = New-Object System.Windows.Media.Imaging.BitmapEncoder
        }
        ElseIf($File.Extension -match "(\.tiff|\.tif)")
        {
            Write-Verbose "Encoder is set to TIFF based on file extension"
            $Encoder = New-Object System.Windows.Media.Imaging.TiffBitmapEncoder
        }
        ElseIf($File.Extension -match "\.wmp")
        {
            Write-Verbose "Encoder is set to WMP based on file extension"
            $Encoder = New-Object System.Windows.Media.Imaging.WmpBitmapEncoder
        }
        ElseIf($File.Extension -match "\.png")
        {
            Write-Verbose "Encoder is set to PNG based on file extension"
            $Encoder = New-Object System.Windows.Media.Imaging.PngBitmapEncoder
        }
        ElseIf($File.Extension -match "\.gif")
        {
            Write-Verbose "Encoder is set to GIF based on file extension"
            $Encoder = New-Object System.Windows.Media.Imaging.GifBitmapEncoder
        }
       
        Write-Verbose "Encoding new image file for $($File.Name)"
        $Encoder.Frames.Add([System.Windows.Media.Imaging.BitmapFrame]::Create($Frame,$Frame.Thumbnail,$MetaData,$Frame.ColorContexts))

        Write-Verbose "Creating new file for $($File.Name)"
        $OutputStream = [System.IO.File]::Open($DestinationPath,[System.IO.FileMode]::Create,[System.IO.FileAccess]::ReadWrite)

        Write-Verbose "Saving new file data for $($File.Name)"
        $Encoder.Save($OutputStream)


        Write-Verbose "Cleaing up streams and old file for $($File.Name)"
        $InputStream.Close()
        $OutputStream.Close()

        Remove-item $SourcePath
        Rename-Item $DestinationPath -NewName $SourcePath
    }
}
 
WOW!!! I cannot believe you have put this much time and effort into this to help a stranger. I can't thank you enough. Yes, it worked! Turns out I was confused about the adjustment I had to make -- I needed to make the .jpg files an hour later, not an hour earlier, but no problem, I just changed the -1 to +1.

Am I naive to believe that it would be easy for me to modify this function to change the Media Created time on my .mp4 files? Seems like I could just change the file extension(s) to be included in the "$Files = Get-ChildItem..." line, and then change the references to "DateTaken" to whatever the correct name is for the Media Created field. "MediaCreated"?

Thank you. Thank you. Thank you.