Marc Freeman
Marc Freeman

Reputation: 753

Parse JS Date.toIsoString in C#

I need to store a JS date as a ISO 8601 date. I'm currently grabbing the date from a form with the format 2019-06-22T00:00:00.000Z as is to be expected from JS' toIsoString() method.

When this date is passed to my API Controller, I've tried using DateTime.ParseExact on the date and passed the format to the method.

I've tried

TS.

private _mapNewShowForm(): ArtistShows {
    let showDate = this.newShowForm.get(this.newShowFormEnum.DATE).value;
    let convertedShowDate = new Date(showDate).toISOString();

    return {
      bandsAlsoPlaying: [],
      showDate: convertedShowDate,
      venue: `${this.newShowForm.get(this.newShowFormEnum.VENUE).value}, ${this.newShowForm.get(this.newShowFormEnum.CITY).value}`
    };
}

C#

var user = _context.Users
                    .Where(x => x.Id == id)
                    .Include(y => y.Artist)
                    .Include(z => z.Artist.Shows)
                    .FirstOrDefault();

                if (user != null)
                {
                    shows.ForEach(x =>
                    {
                        user.Artist.Shows.Add(new ArtistShow
                        {
                            Venue = x.Venue,
                            ShowDate = DateTime.ParseExact(x.ShowDate.ToString(), "YYYY-MM-DDTHH:mm:ss.sssZ", CultureInfo.InvariantCulture),
                            BandsAlsoPlaying = x.BandsAlsoPlaying.Join(","),
                            Id = Guid.NewGuid()
                        });


                    });

                    _context.SaveChanges();

                    return new ShowAddedToArtistDbResponse
                    {
                        ShowAdded = true,
                        UserToken = _encryptionService.GenerateToken(id),
                        NumberOfShowsAdded = shows.Count
                    };   
                }

And

var user = _context.Users
                    .Where(x => x.Id == id)
                    .Include(y => y.Artist)
                    .Include(z => z.Artist.Shows)
                    .FirstOrDefault();

                if (user != null)
                {
                    shows.ForEach(x =>
                    {
                        user.Artist.Shows.Add(new ArtistShow
                        {
                            Venue = x.Venue,
                            ShowDate = ShowDate = DateTime.ParseExact(x.ShowDate, "YYYY-MM-DDTHH:mm:ss.sssZ", CultureInfo.InvariantCulture),
                            BandsAlsoPlaying = x.BandsAlsoPlaying.Join(","),
                            Id = Guid.NewGuid()
                        });


                    });

                    _context.SaveChanges();

                    return new ShowAddedToArtistDbResponse
                    {
                        ShowAdded = true,
                        UserToken = _encryptionService.GenerateToken(id),
                        NumberOfShowsAdded = shows.Count
                    };   
                }

Which throws

System.FormatException: String '2019-06-22T00:00:00.000Z' was not recognized as a valid DateTime.
   at System.DateTime.ParseExact(String s, String format, IFormatProvider provider)
   at socialmediabackendv2.Repositories.UserRepository.<>c__DisplayClass8_1.<AddShowsToArtistInDb>b__3(MappedArtistShow x) in C:\Users\freem\Documents\Projects\socialmediabackendv2\socialmediabackendv2\Repositories\UserRepository.cs:line 256
   at System.Collections.Generic.List`1.ForEach(Action`1 action)
   at socialmediabackendv2.Repositories.UserRepository.AddShowsToArtistInDb(List`1 shows, Guid id) in C:\Users\freem\Documents\Projects\socialmediabackendv2\socialmediabackendv2\Repositories\UserRepository.cs:line 254
   at socialmediabackendv2.Services.UserService.AddNewShowToArtist(StringValues jwtToken, List`1 shows) in C:\Users\freem\Documents\Projects\socialmediabackendv2\socialmediabackendv2\Services\UserService.cs:line 231
   at socialmediabackendv2.Controllers.UsersController.AddNewShow(List`1 newShows) in C:\Users\freem\Documents\Projects\socialmediabackendv2\socialmediabackendv2\Controllers\UsersController.cs:line 41
   at lambda_method(Closure , Object , Object[] )
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
   at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

I am starting to feel like this is a problem with toIsoString() but I'm such a novice when it comes to DateTimes that I didn't know where else to turn. Has anyone else come across this? The date matches the formatting rules but it just seems impossible to parse it.

Upvotes: 2

Views: 2392

Answers (1)

ARr0w
ARr0w

Reputation: 1731

You can use the Convert.ToDateTime() function which also accepts string date format values and converts it into the DateTime object of C#

List<string> objList = new List<string>();
objList.Add("2019-06-22T00:00:00.000Z");    
objList.ForEach(x=> Console.WriteLine( Convert.ToDateTime(x) ));

put this in try-catch, so when any invalid format is received you can handle the exception, log it to enhance your debugging.

for detail information about Convert.ToDateTime(); visit here to microsoft official page

Below is the fiddle to how you can convert the string value to DateTime object from string received from client type script.

C# fiddle

Upvotes: 1

Related Questions