Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
H
HYH.APSJ
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
佟礼
HYH.APSJ
Commits
51cf694a
Commit
51cf694a
authored
Feb 03, 2026
by
DESKTOP-VKRD9QF\Administration
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
http://39.100.78.207:1213/tongli/hyh.apsj
parents
d080df16
250695e0
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
192 additions
and
36 deletions
+192
-36
Machine.java
src/main/java/com/aps/entity/basic/Machine.java
+6
-0
GeneticDecoder.java
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
+145
-21
MachineCalculator.java
...ain/java/com/aps/service/Algorithm/MachineCalculator.java
+7
-4
MaterialRequirementService.java
...com/aps/service/Algorithm/MaterialRequirementService.java
+3
-0
ScheduleOperationService.java
...a/com/aps/service/Algorithm/ScheduleOperationService.java
+29
-1
DiscreteParameterDurationServiceImpl.java
...ps/service/impl/DiscreteParameterDurationServiceImpl.java
+1
-9
PlanResultServiceTest.java
src/test/java/com/aps/demo/PlanResultServiceTest.java
+1
-1
No files found.
src/main/java/com/aps/entity/basic/Machine.java
View file @
51cf694a
package
com
.
aps
.
entity
.
basic
;
import
com.aps.entity.Algorithm.GAScheduleResult
;
import
lombok.Data
;
import
java.util.ArrayList
;
...
...
@@ -27,6 +28,11 @@ public class Machine {
*/
private
int
earliestTime
=
0
;
/**
* 最后的任务,默认值:0
*/
private
GAScheduleResult
lastGene
=
null
;
/**
* 总任务时间
*/
...
...
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
View file @
51cf694a
...
...
@@ -144,17 +144,24 @@ public class GeneticDecoder {
return
chromosome
;
}
public
void
generateGlobalOpList
(
Chromosome
chromosome
)
{
public
int
generateGlobalOpList
(
Chromosome
chromosome
)
{
CopyOnWriteArrayList
<
Entry
>
allOperations
=
chromosome
.
getAllOperations
()
.
stream
()
.
filter
(
t
->
t
.
isNewCreate
()==
true
)
.
collect
(
Collectors
.
toCollection
(
CopyOnWriteArrayList:
:
new
));
if
(
allOperations
==
null
&&
allOperations
.
size
()>
0
)
{
return
0
;
}
List
<
GlobalOperationInfo
>
globalOpList
=
new
ArrayList
<>();
int
globalOpId
=
chromosome
.
getGlobalOpList
()
.
stream
()
.
mapToInt
(
GlobalOperationInfo:
:
getGlobalOpId
)
.
max
().
orElse
(
0
)+
1
;
CopyOnWriteArrayList
<
Entry
>
allOperations
=
chromosome
.
getAllOperations
()
.
stream
()
.
filter
(
t
->
t
.
isNewCreate
()==
true
)
.
collect
(
Collectors
.
toCollection
(
CopyOnWriteArrayList:
:
new
));
for
(
Entry
op
:
allOperations
)
{
GlobalOperationInfo
info
=
new
GlobalOperationInfo
();
...
...
@@ -168,7 +175,7 @@ public class GeneticDecoder {
Initialization
initialization
=
new
Initialization
();
initialization
.
generateInitialSFPopulation
(
chromosome
,
globalOpList
);
chromosome
.
getGlobalOpList
().
addAll
(
globalOpList
);
return
1
;
}
private
void
CreateNewOpSequence
(
Chromosome
chromosome
)
...
...
@@ -275,10 +282,12 @@ if(finishedOrder==null||finishedOrder.size()==0)
List
<
OrderMaterialRequirement
>
orderMaterials
=
materialRequirementService
.
buildMultiLevelRequirementNetwork
(
chromosome
,
sceneId
,
baseTime
,
_globalParam
);
if
(
orderMaterials
!=
null
&&
orderMaterials
.
size
()>
0
&&
_globalParam
.
isIsCheckSf
())
{
generateGlobalOpList
(
chromosome
);
if
(
_globalParam
.
isIsCheckSf
())
{
int
isnew
=
generateGlobalOpList
(
chromosome
);
CreateNewOpSequence
(
chromosome
);
if
(
isnew
==
1
)
{
CreateNewOpSequence
(
chromosome
);
}
}
List
<
GlobalOperationInfo
>
globalOpList
=
chromosome
.
getGlobalOpList
();
...
...
@@ -474,18 +483,27 @@ if(finishedOrder==null||finishedOrder.size()==0)
}
int
setupTime
=
0
;
CopyOnWriteArrayList
<
GAScheduleResult
>
machineTasks
=
chromosome
.
getResult
().
stream
()
.
filter
(
t
->
t
.
getMachineId
()
==
machine
.
getId
())
.
sorted
(
Comparator
.
comparingInt
(
GAScheduleResult:
:
getStartTime
))
.
collect
(
Collectors
.
toCollection
(
CopyOnWriteArrayList:
:
new
));
// _globalParam.set_smoothChangeOver(false);
CopyOnWriteArrayList
<
GAScheduleResult
>
machineTasks
=
null
;
// CopyOnWriteArrayList<GAScheduleResult> machineTasks =chromosome.getResult().stream()
// .filter(t -> t.getMachineId() == machine.getId())
// .sorted(Comparator.comparingInt(GAScheduleResult::getStartTime))
// .collect(Collectors.toCollection(CopyOnWriteArrayList::new));
GAScheduleResult
lastGeneOnMachine
=
machine
.
getLastGene
();
if
(
lastGeneOnMachine
!=
null
)
{
earliestStartTime
=
Math
.
max
(
earliestStartTime
,
lastGeneOnMachine
.
getEndTime
());
}
// _globalParam.set_smoothChangeOver(false);
CopyOnWriteArrayList
<
ScheduleResultDetail
>
geneDetails
=
new
CopyOnWriteArrayList
<>();
int
bomtime
=
0
;
if
((
operation
.
getMaterialRequirements
()!=
null
&&
operation
.
getTargetFinishedOperationId
()==
null
)||
calbom
)
{
int
earliestStartTimeold
=
earliestStartTime
;
if
(
_globalParam
.
is_smoothChangeOver
())
{
Map
<
Integer
,
Object
>
reslte
=
calculateSetupTime
(
machine
Tasks
,
operation
,
machine
,
earliestStartTime
,
processingTimeTotal
,
_globalParam
.
is_smoothChangeOverInWeek
(),
""
,
null
);
Map
<
Integer
,
Object
>
reslte
=
calculateSetupTime
(
machine
.
getLastGene
(),
operation
,
machine
,
earliestStartTime
,
processingTimeTotal
,
_globalParam
.
is_smoothChangeOverInWeek
(),
chromosome
.
getAllOperations
()
);
// setupTime = (int) reslte.get(1);//换型时间
// int setupStartTime = (int) reslte.get(2);//换型开始时间
//earliestStartTime=(int)reslte.get(3);//上个任务的结束时间
...
...
@@ -505,7 +523,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
if
(
_globalParam
.
is_smoothChangeOver
())
{
//是否考虑换型时间
Map
<
Integer
,
Object
>
reslte
=
calculateSetupTime
(
machine
Tasks
,
operation
,
machine
,
earliestStartTime
,
processingTimeTotal
,
_globalParam
.
is_smoothChangeOverInWeek
(),
""
,
null
);
Map
<
Integer
,
Object
>
reslte
=
calculateSetupTime
(
machine
.
getLastGene
(),
operation
,
machine
,
earliestStartTime
,
processingTimeTotal
,
_globalParam
.
is_smoothChangeOverInWeek
(),
chromosome
.
getAllOperations
()
);
setupTime
=(
int
)
reslte
.
get
(
1
);
//换型时间
int
setupStartTime
=(
int
)
reslte
.
get
(
2
);
//换型开始时间
//earliestStartTime=(int)reslte.get(3);//上个任务的结束时间
...
...
@@ -514,7 +532,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
if
(
setupTime
==
0
)
{
geneDetails
=
machineCalculator
.
getNextAvailableTime
(
machine
,
earliestStartTime
,
-
1
,
processingTimeTotal
,
chromosome
.
getResult
()
,
operation
.
IsInterrupt
!=
1
,
true
,
processingTime
,
operation
.
getQuantity
(),
true
);
processingTimeTotal
,
machineTasks
,
operation
.
IsInterrupt
!=
1
,
true
,
processingTime
,
operation
.
getQuantity
(),
true
);
}
else
{
CopyOnWriteArrayList
<
TimeSegment
>
AvailableTimeSegment
=
(
CopyOnWriteArrayList
<
TimeSegment
>)
reslte
.
get
(
6
);
...
...
@@ -629,7 +647,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
// System.out.println("huanxingshijian="+result.getChangeOverTime()+"-------------------"+result.getOrderId()+"--------"+result.getExecId()+"---------"+prev.getOrderId()+"--------"+prev.getExecId());
chromosome
.
getResult
().
add
(
result
);
machine
.
setLastGene
(
result
);
// FileHelper.writeLogFile(" 结束 "+ConvertTime(startTime)+"--"+ConvertTime(endTime)+" "+operation.getGroupId()+" : "+operation.getId()+",处理时间: " + processingTime + ", 后处理: " + teardownTime +
// ", 前处理: " + preTime + ", 换型: " + setupTime+ ", 数量: " + operation.getQuantity()+ ", 设备: "+machine.getId()+ ", 是否可中断: "+operation.getIsInterrupt());
...
...
@@ -1118,7 +1136,109 @@ return getOperationBOMTime(currentOp, chromosome);
private
String
ConvertTime
(
int
minute
)
{
return
baseTime
.
plusSeconds
(
minute
).
format
(
java
.
time
.
format
.
DateTimeFormatter
.
ofPattern
(
"YYYY-MM-dd HH:mm"
));
}
private
Map
<
Integer
,
Object
>
calculateSetupTime
(
CopyOnWriteArrayList
<
GAScheduleResult
>
machineTasks
,
Entry
operation
,
Machine
machine
,
int
earliestStartTime
,
int
processingTimeTotal
,
boolean
changeOverInWeek
,
String
lastExecId
,
Map
<
Integer
,
Object
>
lastsetupTime
)
{
private
Map
<
Integer
,
Object
>
calculateSetupTime
(
GAScheduleResult
lastGeneOnMachine
,
Entry
operation
,
Machine
machine
,
int
earliestStartTime
,
int
processingTimeTotal
,
boolean
changeOverInWeek
,
List
<
Entry
>
allOperations
)
{
Map
<
Integer
,
Object
>
reslte
=
new
HashMap
<>();
reslte
.
put
(
1
,
0
);
//换型时间
reslte
.
put
(
2
,
0
);
//换型开始时间
reslte
.
put
(
3
,
0
);
//上个任务的结束时间
reslte
.
put
(
4
,
earliestStartTime
);
//最早开工时间
reslte
.
put
(
5
,
processingTimeTotal
);
//总加工时长
if
(
lastGeneOnMachine
==
null
)
{
return
reslte
;
}
// LocalDateTime startTime = baseTime.plus(earliestStartTime, ChronoUnit.SECONDS);
reslte
.
put
(
3
,
lastGeneOnMachine
.
getEndTime
());
//换型开始时间
String
ExecId
=
lastGeneOnMachine
.
getExecId
();
Entry
prev
=
allOperations
.
stream
().
filter
(
t
->
t
.
getExecId
().
equals
(
ExecId
))
.
findFirst
().
orElse
(
null
);
int
setupTime
=
0
;
if
(
prev
!=
null
)
{
//离散参数
// prev.getDiscreteParameter()
// setupTime = (prev.getProductId() != operation.getProductId())
// ? (int) discreteParameterMatrixService.getDiscreteParameterMatrixValue(prev, operation)
// : 0;
DiscreteParameterMatrixService
discreteParameterMatrixService
=
SpringContextUtil
.
getBean
(
DiscreteParameterMatrixService
.
class
);
DiscreteParameterDurationService
discreteParameterDurationService
=
SpringContextUtil
.
getBean
(
DiscreteParameterDurationService
.
class
);
double
discreteParameterDurationValue
=
discreteParameterDurationService
.
calculateChangeoverTime
(
prev
,
operation
,
machine
,
allOperations
,
earliestStartTime
,
null
);
double
discreteParameterMatrixValue
=
discreteParameterMatrixService
.
getDiscreteParameterMatrixValue
(
operation
,
prev
);
setupTime
=
(
int
)
Math
.
max
(
discreteParameterDurationValue
,
discreteParameterMatrixValue
);
// setupTime = (int) discreteParameterMatrixValue;
// System.out.println("换型时间"+discreteParameterMatrixValue);
// System.out.println(setupTime+"换型时间"+"huanxingshijian ");
}
// setupTime=20*3600;
operation
.
setChangeLineTime
(
setupTime
);
reslte
.
put
(
1
,
setupTime
);
//换型时间
if
(
changeOverInWeek
)
//可以放到休息时间
{
CopyOnWriteArrayList
<
TimeSegment
>
AvailableTimeSegment
=
machineCalculator
.
getMachineAvailableTime
(
machine
,
earliestStartTime
+
setupTime
,
processingTimeTotal
,
null
,
operation
.
IsInterrupt
!=
1
);
if
(
AvailableTimeSegment
!=
null
)
{
reslte
.
put
(
6
,
AvailableTimeSegment
);
int
start
=
(
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
AvailableTimeSegment
.
get
(
0
).
getStart
());
earliestStartTime
=
earliestStartTime
>
start
?
earliestStartTime
:
start
;
reslte
.
put
(
4
,
earliestStartTime
);
//最早开工时间
reslte
.
put
(
2
,
earliestStartTime
-
setupTime
);
//换型开始时间
}
//01 16:00 +20 -01 16:00 02 12:00 08:00 -18:00 01 16:18 02 08:00-12:00
//01 16:00 +10 -01 16:00 换型10:00 08:00
//01 18:00 +10 -02 08:00<0 换型 休息时间满足
//01 18:00 +20 -02 08:00>0
//01 18:00 +10 -02 00:00>0
return
reslte
;
}
else
{
//开始时间加上设置时间重新算
//如果是前提供任务是相同的则跳出
CopyOnWriteArrayList
<
TimeSegment
>
AvailableTimeSegment
=
machineCalculator
.
getMachineAvailableTime
(
machine
,
earliestStartTime
,
processingTimeTotal
+
setupTime
,
null
,
operation
.
IsInterrupt
!=
1
);
if
(
AvailableTimeSegment
!=
null
)
{
reslte
.
put
(
6
,
AvailableTimeSegment
);
int
start
=
(
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
AvailableTimeSegment
.
get
(
0
).
getStart
());
earliestStartTime
=
earliestStartTime
>
start
?
earliestStartTime
:
start
;
reslte
.
put
(
4
,
earliestStartTime
);
//最早开工时间
reslte
.
put
(
2
,
earliestStartTime
);
//换型开始时间
reslte
.
put
(
5
,
processingTimeTotal
+
setupTime
);
//换型开始时间
}
}
// System.out.println("换型时间111"+setupTime);
return
reslte
;
}
private
Map
<
Integer
,
Object
>
calculateSetupTime1
(
CopyOnWriteArrayList
<
GAScheduleResult
>
machineTasks
,
Entry
operation
,
Machine
machine
,
int
earliestStartTime
,
int
processingTimeTotal
,
boolean
changeOverInWeek
,
String
lastExecId
,
Map
<
Integer
,
Object
>
lastsetupTime
)
{
Map
<
Integer
,
Object
>
reslte
=
new
HashMap
<>();
reslte
.
put
(
1
,
0
);
//换型时间
...
...
@@ -1133,6 +1253,10 @@ return getOperationBOMTime(currentOp, chromosome);
// LocalDateTime startTime = baseTime.plus(earliestStartTime, ChronoUnit.SECONDS);
GAScheduleResult
lastGeneOnMachine
=
machineTasks
.
get
(
machineTasks
.
size
()-
1
);
if
(
lastGeneOnMachine
.
getEndTime
()>
earliestStartTime
)
{
CopyOnWriteArrayList
<
TimeSegment
>
AvailableTimeSegment
=
machineCalculator
.
getMachineAvailableTime
(
machine
,
earliestStartTime
,
...
...
@@ -1229,7 +1353,7 @@ return getOperationBOMTime(currentOp, chromosome);
{
cha
=
cha
+
1
;
//加1是工序开始加工时间
reslte
.
put
(
2
,
lastGeneOnMachine
.
getEndTime
());
//换型开始时间
reslte
=
calculateSetupTime
(
machineTasks
,
operation
,
machine
,
earliestStartTime
+
cha
,
processingTimeTotal
,
_globalParam
.
is_smoothChangeOverInWeek
(),
ExecId
,
reslte
);
//
reslte = calculateSetupTime(machineTasks, operation, machine,earliestStartTime+cha,processingTimeTotal, _globalParam.is_smoothChangeOverInWeek(), ExecId,reslte);
}
else
{
...
...
@@ -1242,7 +1366,7 @@ return getOperationBOMTime(currentOp, chromosome);
//开始时间加上设置时间重新算
//如果是前提供任务是相同的则跳出
reslte
=
calculateSetupTime
(
machineTasks
,
operation
,
machine
,
earliestStartTime
,
processingTimeTotal
+
setupTime
,
_globalParam
.
is_smoothChangeOverInWeek
(),
ExecId
,
reslte
);
//
reslte = calculateSetupTime(machineTasks, operation, machine,earliestStartTime,processingTimeTotal+setupTime, _globalParam.is_smoothChangeOverInWeek(),ExecId,reslte);
}
...
...
src/main/java/com/aps/service/Algorithm/MachineCalculator.java
View file @
51cf694a
...
...
@@ -271,10 +271,13 @@ public class MachineCalculator {
Machine
machine
,
int
processingTime
,
LocalDateTime
currentTime
,
String
prevtime
,
CopyOnWriteArrayList
<
GAScheduleResult
>
existingTasks
,
double
oneTime
,
double
quantity
,
boolean
checkprevtime
,
boolean
islockMachineTime
,
boolean
isInterrupt
)
{
CopyOnWriteArrayList
<
GAScheduleResult
>
machineTasks
=
existingTasks
.
stream
()
.
filter
(
t
->
t
.
getMachineId
()
==
machine
.
getId
())
.
sorted
(
Comparator
.
comparingInt
(
GAScheduleResult:
:
getStartTime
))
.
collect
(
Collectors
.
toCollection
(
CopyOnWriteArrayList:
:
new
));
CopyOnWriteArrayList
<
GAScheduleResult
>
machineTasks
=
null
;
if
(
existingTasks
!=
null
)
{
machineTasks
=
existingTasks
.
stream
()
.
filter
(
t
->
t
.
getMachineId
()
==
machine
.
getId
())
.
sorted
(
Comparator
.
comparingInt
(
GAScheduleResult:
:
getStartTime
))
.
collect
(
Collectors
.
toCollection
(
CopyOnWriteArrayList:
:
new
));
}
CopyOnWriteArrayList
<
ScheduleResultDetail
>
times
=
new
CopyOnWriteArrayList
<>();
...
...
src/main/java/com/aps/service/Algorithm/MaterialRequirementService.java
View file @
51cf694a
...
...
@@ -276,6 +276,8 @@ public class MaterialRequirementService {
.
eq
(
Routingsupporting:
:
getIsdeleted
,
0
);
routingsupportings1
=
routingsupportingMapper
.
selectList
(
routingsupportingwrapper
);
if
(
routingsupportings1
!=
null
&&
routingsupportings1
.
size
()>
0
)
{
routingsupportings
.
addAll
(
routingsupportings1
);
List
<
String
>
routingsupportingids
=
routingsupportings1
.
stream
()
...
...
@@ -338,6 +340,7 @@ public class MaterialRequirementService {
}
}
}
}
}
if
(
routingIds1
!=
null
)
{
...
...
src/main/java/com/aps/service/Algorithm/ScheduleOperationService.java
View file @
51cf694a
...
...
@@ -201,7 +201,6 @@ int newStartTime=0;
}
/**
* 移动工序方法
* @param chromosome 染色体对象
...
...
@@ -212,6 +211,35 @@ int newStartTime=0;
public
void
moveOperation
(
Chromosome
chromosome
,
List
<
Integer
>
opIds
,
int
newStartTime
,
Long
newMachineId
,
GlobalParam
globalParam
,
int
lockStartTime
)
{
List
<
Entry
>
allOperations
=
chromosome
.
getAllOperations
();
for
(
Integer
opId:
opIds
)
{
GAScheduleResult
targetResults
=
chromosome
.
getResult
().
stream
()
.
filter
(
r
->
r
.
getOperationId
()
==
opId
).
findFirst
()
.
orElseThrow
(()
->
new
NoSuchElementException
(
"Operation not found: "
+
opId
));
targetResults
.
setLockStartTime
(
1
);
targetResults
.
setDesignatedStartTime
(
newStartTime
);
Entry
targetOp
=
allOperations
.
stream
()
.
filter
(
o
->
o
.
getId
()
==
opId
)
.
findFirst
()
.
orElseThrow
(()
->
new
NoSuchElementException
(
"Operation not found: "
+
opId
));
targetOp
.
setDesignatedStartTime
(
chromosome
.
getBaseTime
().
plusSeconds
(
newStartTime
));
}
redecode
(
chromosome
,
chromosome
.
getBaseTime
(),
globalParam
);
}
/**
* 移动工序方法
* @param chromosome 染色体对象
* @param opIds 工序ID
* @param newStartTime 新开始时间
* @param newMachineId 新设备ID
*/
public
void
moveOperation1
(
Chromosome
chromosome
,
List
<
Integer
>
opIds
,
int
newStartTime
,
Long
newMachineId
,
GlobalParam
globalParam
,
int
lockStartTime
)
{
List
<
Entry
>
allOperations
=
chromosome
.
getAllOperations
();
int
newStartTime1
=
newStartTime
;
...
...
src/main/java/com/aps/service/impl/DiscreteParameterDurationServiceImpl.java
View file @
51cf694a
...
...
@@ -28,7 +28,7 @@ public class DiscreteParameterDurationServiceImpl extends ServiceImpl<DiscretePa
Machine
machine
,
List
<
Entry
>
allOperations
,
int
startTime
,
List
<
GAScheduleResult
>
machineTasks
)
{
if
(
machineTasks
.
isEmpty
())
{
if
(
machineTasks
==
null
||
machineTasks
.
isEmpty
())
{
return
0.0
;
}
...
...
@@ -38,15 +38,7 @@ public class DiscreteParameterDurationServiceImpl extends ServiceImpl<DiscretePa
return
0.0
;
}
// 获取设备上最后一个任务
GAScheduleResult
lastGene
=
machineTasks
.
stream
()
.
filter
(
g
->
g
.
getMachineId
()
==
machine
.
getId
())
.
max
(
Comparator
.
comparingInt
(
GAScheduleResult:
:
getEndTime
))
.
orElse
(
null
);
if
(
lastGene
==
null
)
{
return
0.0
;
}
...
...
src/test/java/com/aps/demo/PlanResultServiceTest.java
View file @
51cf694a
...
...
@@ -39,7 +39,7 @@ public class PlanResultServiceTest {
// TestSortService sortService=new TestSortService();
// sortService.test1();
// nsgaiiUtils.Test();
planResultService
.
execute2
(
"
EDDAFBAC0BD84375B7CF89BC85255082
"
);
planResultService
.
execute2
(
"
18E5F8BE09B14EAE822651BFEF100900
"
);
// planResultService.execute2("726D4C1A712B4B1393175BD44B775B66");
// planResultService.execute2("265F24B6DF3C40E4B17D193B0CC8AAF2");
// LocalDateTime t= LocalDateTime.of(2026, 02, 14, 1, 25, 52);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment