当前位置:网站首页>Unity 之 切换语言导致报错:System.FormatException:String was not recognized as a valid DateTime.
Unity 之 切换语言导致报错:System.FormatException:String was not recognized as a valid DateTime.
2022-07-28 17:06:00 【陈言必行】
Unity 之 切换语言导致报错:System.FormatException:String was not recognized as a valid DateTime.
一,发生问题
1.1 问题背景
最近在开发多语言本地化时(简体-繁体来回切换),发生了这个错误:System.FormatException: String was not recognized as a valid DateTime. --> 系统格式异常:字符串未被识别为有效的日期时间。
看起来是逻辑上错误传了一个错误的字符串给DateTime.Parse(“”)方法作为参数了。那么奇怪的是在编辑器下没有发生错误,在真机不切换语言的情况也没有发生错误,只有在IOS切换简繁体系统语言时会发生这个错误。
于是猜测在不同语言环境下DateTime.Now.ToString()得到的结果是不同的,所以就有了2.1的测试用例。
1.2 报错日志
真机切换语言捕获的错误日志:
System.AggregateException: One or more errors occurred. ---> System.FormatException: String was not recognized as a valid DateTime.
at System.DateTimeParse.Parse (System.String s, System.Globalization.DateTimeFormatInfo dtfi, System.Globalization.DateTimeStyles styles) [0x00000] in <00000000000000000000000000000000>:0
at WZC.ActivityManager+<>c__DisplayClass45_0.<GetActivitySwitchConfig>b__0 (WZC.ActivitySwitchConfig e) [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.ContextCallback.Invoke (System.Object state) [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <00000000000000000000000000000000>:0
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner.Run () [0x00000] in <00000000000000000000000000000000>:0
at System.Action.Invoke () [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.ContextCallback.Invoke (System.Object state) [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.Tasks.AwaitTaskContinuation.RunCallback (System.Threading.ContextCallback callback, System.Object state, System.Threading.Tasks.Task& currentTask) [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.Tasks.Task`1[TResult].TrySetResult (TResult result) [0x00000] in <00000000000000000000000000000000>:0
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[TResult].Create () [0x00000] in <00000000000000000000000000000000>:0
at WZC.ApiHelper..cctor () [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.ContextCallback.Invoke (System.Object state) [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <00000000000000000000000000000000>:0
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner.Run () [0x00000] in <00000000000000000000000000000000>:0
at System.Action.Invoke () [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.ContextCallback.Invoke (System.Object state) [0x00000] in <00000000000000000000000000000000>:0
--- End of inner exception stack trace ---
二,定位问题
2.1 测试用例
按照游戏逻辑还原了DateTime的使用情况,为了方便观察日志创建了Scroll View组件,里面放一个很长的Text,测试代码和场景搭建效果如下:
using System;
using UnityEngine;
using UnityEngine.UI;
public class ConverTimeError : MonoBehaviour
{
public Text context;
public Button cunShiJian;
public Button quShiJian;
void Start()
{
var strRus = PlayerPrefs.GetString("Hall:RegionGetDate");
var strRusDate = DateTime.Parse(strRus);
context.text += "转换结果:+++" + strRusDate.Year + "/" + strRusDate.Month+ "/" + strRusDate.Day + ";\n";
cunShiJian.onClick.AddListener(()=>{
context.text += "存时间 :---" + DateTime.Now + ";\n";
PlayerPrefs.SetString("Hall:RegionGetDate", DateTime.Now.ToString());
context.text += "存储结果:---" + PlayerPrefs.GetString("Hall:RegionGetDate") + ";\n";
});
quShiJian.onClick.AddListener(()=>{
context.text += "取时间 :+++" + DateTime.Now + ";\n";
var regionGetDateStr = PlayerPrefs.GetString("Hall:RegionGetDate");
context.text += "取到结果:+++" + regionGetDateStr + ";\n";
var regionGetDate = DateTime.Parse(regionGetDateStr);
context.text += "取到转换结果:+++" + regionGetDate.Year + "/" + regionGetDate.Month+ "/" + regionGetDate.Day + ";\n";
});
}
}

使用此测试用例在macOS和IOS上都进行了切换语言的测试,结果都没有任何异常,发现DateTime.Now.ToString()的结果都是:月/日/年 时:分:秒 这种格式。

2.2 找到问题
测试用例没发现问题,那不得不在原工程中补日志了,几经周折最后确定了有一个存时间的字符串格式为日/月/年 时:分:秒
于是在编辑器中模拟转换了年/月/日,月/日/年和日/月/年 三种格式的时间转换:
Debug.Log("年/月/日: " + DateTime.Parse("2022/7/25 13:11:00"));
Debug.Log("月/日/年: " + DateTime.Parse("7/25/2022 13:11:00"));
// 有问题的时间格式转换
Debug.Log("日/月/年: " + DateTime.Parse("25/7/2022 13:11:00"));

结果表明:日/月/年这种格式的字符串确实不能使用DateTime.Parse()方法进行转换。
那么新的问题就来了,在时间存储时使用的是:DateTime.Now.ToString(),而在2.1的测试用例中我们有确认了DateTime.Now.ToString()的结果都是:月/日/年 时:分:秒 这种格式。
同时又可以确定的是游戏中存储时间使用的都是DateTime.Now.ToString()这种形式,这就很让人费解游戏逻辑中日/月/年格式的字符串是怎么出来的呢?
三,解决问题
3.1 尝试解决
刚开始是使用了
DateTime.ParseExact(DateTime.Now.ToString(), "yyyy/dd/MM", System.Globalization.CultureInfo.InvariantCulture);
这个方法来进行格式转换,因为这是指定格式的转换,所以根据上面的测试结果也是不行的。
3.2 解决问题
将存储的代码固定格式为:
DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss")
好在工程里面只有几处DateTime.Now的赋值,修改起来还是很方便的。最后也测试通过了。
遇到了这么奇怪的问题,记录一下,供遇到相似问题童鞋参考一下。
边栏推荐
- 冒泡排序和相关视频
- 不理解模块化、组件化、插件化的区别怎么行?
- 1.2、队列
- Docker builds MySQL master-slave replication
- Ue5 gas learning notes 1.9 skill system global classes (abilitysystemglobals)
- DC simulation example of ADS simulation
- mysql 索引使用与优化
- 高德地图实现自定义小蓝点 自定义点标记 绘制多边形/圆形区域 根据地图的移动显示或者隐藏自定义点标记的相关实现
- Introduction and advanced level of MySQL (8)
- There is a special cryptology language called asn.1
猜你喜欢

MYSQL入门与进阶(四)

Experimental building - PHP Dafa

Gateway入门

DC simulation example of ADS simulation

Random talk on GIS data (VI) - projection coordinate system

APP为什么用JSON协议与服务端交互:序列化相关知识

Detailed explanation of oscilloscope parameters

.net WCF WF4.5 状态机、书签与持久化

Introduction to CC cable of USB type-C

直播|StarRocks 技术内幕 :低基数全局字典优化
随机推荐
数字化转型中的DevOps——弹性合作
Software testing needs more and more talents, but fewer people are on the road of testing?
当Golang遇到高并发秒杀
Brief introduction to the principle of spectrometer II
MYSQL入门与进阶(三)
Introduction and advanced level of MySQL (10)
Go并发详解之一
Introduction to advanced design system (ads) 2009 RF simulation
MYSQL入门与进阶(二)
十进制转二进制进阶版(可转化负数以及边界值)
haproxy实现灰度发布
Ue5 gas learning notes 8.0 references
[GXYCTF2019]StrongestMind
Wired: who owns the art of the future? Openai allows dall-e users to commercialize their works. At present
从 SRE 看 DevOps 建设
MySQL index usage and optimization
GO exe生成图标版本信息
ERROR 2003 (HY000) Can‘t connect to MySQL server on ‘localhost3306‘ (10061)解决办法
.net WCF WF4.5 状态机、书签与持久化
Ue5 gas learning notes 1.1 capability system component